これは非常に一般的な問題であり、Miguel が提案したように AOP アプローチを選択する大きな理由であるため、INotifyPropertyChanged (プロパティ セットをインターセプトしてイベントを発生させる) の実装を示すAfterthoughtの例を作成しました。
Afterthought を使用すると、プロパティのインターセプトを非常に簡単に記述できます。具体的には、プロパティの前後の値を提供することで、プロパティ セットのインターセプトを簡単にします。インターセプトするプロパティを特定するには、次のようにします。
public override void Amend<TProperty>(Property<TProperty> property)
{
// Raise property change notifications
if (property.PropertyInfo.CanRead && property.PropertyInfo.CanWrite)
property.AfterSet = NotificationAmender<T>.OnPropertyChanged<TProperty>;
}
OnPropertyChanged
この場合、次のような静的メソッドを呼び出します。
public static void OnPropertyChanged<P>(INotifyPropertyChangedAmendment instance, string property, P oldValue, P value, P newValue)
{
// Only raise property changed if the value of the property actually changed
if ((oldValue == null ^ newValue == null) || (oldValue != null && !oldValue.Equals(newValue)))
instance.OnPropertyChanged(new PropertyChangedEventArgs(property));
}
したがって、元のプロパティが次のようになっているとします。
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Afterthought を使用して上記の修正を適用すると、次のようになります。
string name;
public string Name
{
get
{
return name;
}
set
{
string oldValue = Name;
name = value;
NotificationAmender<ConcreteClass>.OnPropertyChanged<string>(
this, "Name", oldValue, value, Name);
}
}
あなたの場合、セッターの後(または前)に呼び出される静的メソッドは、好きな名前を付けて、好きなことをすることができます。これは、プロパティ セッターをインターセプトする具体的でよく知られた理由の例にすぎません。プロパティが非仮想であることがわかっている場合、インターセプトを実行するプロキシ サブクラスを作成することはできないため、Afterthought や PostSharp などの AOP アプローチが最善の策であると思います。
また、Afterthought を使用すると、結果のアセンブリが Afterthought への参照や依存関係を持たないようにインターセプトを実装できます。また、インターセプト ロジックがターゲット タイプの API を実際に追加/変更しない場合、理由はありません。具体的なクラスは結果に問題があります。