<t>Without using something like postsharp, the minimal version I use uses something like:<br/>
<br/>
public class Data : INotifyPropertyChanged<br/>
{<br/>
// boiler-plate<br/>
public event PropertyChangedEventHandler PropertyChanged;<br/>
protected virtual void OnPropertyChanged(string propertyName)<br/>
{<br/>
PropertyChangedEventHandler handler = PropertyChanged;<br/>
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));<br/>
}<br/>
protected bool SetField(ref T field, T value, string propertyName)<br/>
{<br/>
if (EqualityComparer.Default.Equals(field, value)) return false;<br/>
field = value;<br/>
OnPropertyChanged(propertyName);<br/>
return true;<br/>
}<br/>
<br/>
// props<br/>
private string name;<br/>
public string Name<br/>
{<br/>
get { return name; }<br/>
set { SetField(ref name, value, "Name"); }<br/>
}<br/>
}<br/>
<br/>
```<br/>
<br/>
Each property is then just something like:<br/>
<br/>
```<br/>
private string name;<br/>
public string Name<br/>
{<br/>
get { return name; }<br/>
set { SetField(ref name, value, "Name"); }<br/>
}<br/>
<br/>
```<br/>
<br/>
which isn't huge; it can also be used as a base-class if you want. The `bool` return from `SetField` tells you if it was a no-op, in case you want to apply other logic.<br/>
<br/>
or even easier with C# 5:<br/>
<br/>
```<br/>
protected bool SetField(ref T field, T value,<br/>
[CallerMemberName] string propertyName = null)<br/>
{...}<br/>
<br/>
```<br/>
<br/>
which can be called like this:<br/>
<br/>
```<br/>
set { SetField(ref name, value); }<br/>
<br/>
```<br/>
<br/>
with which the compiler will add the `"Name"` automatically.<br/>
<br/>
C# 6.0 makes the implementation easier:<br/>
<br/>
```<br/>
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)<br/>
{<br/>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));<br/>
}<br/>
<br/>
```<br/>
<br/>
...and now with C#7:<br/>
<br/>
```<br/>
protected void OnPropertyChanged(string propertyName)<br/>
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));<br/>
<br/>
protected bool SetField(ref T field, T value,[CallerMemberName] string propertyName = null)<br/>
{<br/>
if (EqualityComparer.Default.Equals(fiel<br/>
<br/>
*(Réponse tronquée)*</t>