There are certain things that do require inheritance. In absence of other language features, this example would be one of them. Note that the phrase is to favorfavor composition over inheritance. That does not mean throw out inheritance where it is warranted.
However, C# specifically does provide a nice out here. That's the use of Extension Methods. Since INotifyPropertyChanged declares the event and the identifies the behavioral pattern, you can implement the specific feature you are talking about using this feature:
public static class FrameworkExtensions
{
public static void NotifyPropertyChanged(this INotifyPropertyChanged model,
[CallerMemberName] string property)
= {"")
// Just in case model is null add the check there too{
model?.PropertyChanged?.Invoke(model, new PropertyChangedEventArgs(property));
}
}
The important thing to make it a reality is that the user needs to import the namespace this is declared in. If there are other framework classes that are commonly used in code, that is probably done for you.