6

最近PostSharpの実験を開始しましたが、INotifyPropertyChangedの実装を自動化するのに特に役立つ側面を見つけました。ここで例を見ることができます。基本的な機能は優れていますが(すべてのプロパティが通知されます)、通知を抑制したい場合があります。

たとえば、特定のプロパティがコンストラクターで一度設定され、二度と変更されないことを知っているかもしれません。そのため、NotifyPropertyChangedのコードを発行する必要はありません。クラスが頻繁にインスタンス化されない場合、オーバーヘッドは最小限に抑えられます。自動生成されたプロパティからフィールドに基づくプロパティに切り替えてフィールドに書き込むことで、問題を防ぐことができます。ただし、この新しいツールを学習しているときに、コード生成を抑制する属性でプロパティにタグを付ける方法があるかどうかを知っておくと役に立ちます。私はこのようなことをしたいと思っています:

[NotifyPropertyChanged]
public class MyClass
{
    public double SomeValue { get; set; }

    public double ModifiedValue { get; private set; }

    [SuppressNotify]
    public double OnlySetOnce { get; private set; }

    public MyClass()
    {
        OnlySetOnce = 1.0;
    }
}
4

3 に答える 3

5

MulticastPointcutの代わりにMethodPointcutを使用できます。つまり、Linq-over-Reflectionを使用して、PropertyInfo.IsDefined(属性)に対してフィルターをかけます。

  private IEnumerable<PropertyInfo> SelectProperties( Type type )
    {
        const BindingFlags bindingFlags = BindingFlags.Instance | 
            BindingFlags.DeclaredOnly
                                          | BindingFlags.Public;

        return from property
                   in type.GetProperties( bindingFlags )
               where property.CanWrite &&
                     !property.IsDefined(typeof(SuppressNotify))
               select property;
    }

    [OnLocationSetValueAdvice, MethodPointcut( "SelectProperties" )]
    public void OnSetValue( LocationInterceptionArgs args )
    {
        if ( args.Value != args.GetCurrentValue() )
        {
            args.ProceedSetValue();

           this.OnPropertyChangedMethod.Invoke(null);
        }
    }
于 2010-03-07T18:46:27.900 に答える
3

もう1つの簡単な方法は、次を使用します。

[NotifyPropertyChanged(AttributeExclude=true)]

...特定のメソッドの属性を抑制します。これは、クラスにグローバル属性がアタッチされている場合でも機能します(上記の例のように)。

完全なサンプルコードは次のとおりです。

[NotifyPropertyChanged]
public class MyClass
{
    public double SomeValue { get; set; }

    public double ModifiedValue { get; private set; }

    [NotifyPropertyChanged(AttributeExclude=True)]
    public double OnlySetOnce { get; private set; }

    public MyClass()
    {
        OnlySetOnce = 1.0;
    }
}

この行を追加すると、PostSharpはMSVS GUIを更新して、メソッドにアタッチされている属性を示す下線を削除します。もちろん、デバッガーを実行すると、その特定のメソッドの属性の実行はスキップされます。

于 2010-11-02T18:29:05.647 に答える
0

参考までに、Sharpcrafters Webサイトの例に問題があり、次の変更を行う必要がありました。

    /// <summary>
    /// Field bound at runtime to a delegate of the method <c>OnPropertyChanged</c>.
    /// </summary>
    [ImportMember("OnPropertyChanged", IsRequired = true, Order = ImportMemberOrder.AfterIntroductions)]
    public Action<string> OnPropertyChangedMethod;

OnPropertyChangedメンバーを導入していたと思いますが、作成される前にインポートしました。this.OnPropertyChangedMethodがnullであるため、これによりOnPropertySetが失敗します。

于 2010-03-09T03:45:12.397 に答える