2010-03-07 73 views
6

我最近開始嘗試使用PostSharp,並且發現了一個特別有用的方面來自動執行INotifyPropertyChanged。您可以看到示例here。基本功能非常好(所有屬性都會通知),但有些情況下我可能想要禁止通知。例如,我可能知道某個特定屬性在構造函數中設置了一次,並且不會再發生變化。因此,不需要發出NotifyPropertyChanged的代碼。當類不經常實例化時,開銷很小,我可以通過從自動生成的屬性切換到字段支持的屬性並寫入字段來防止出現問題。但是,當我學習這個新工具時,知道是否有一種方法來標記具有屬性的屬性來抑制代碼生成會很有幫助。我希望能夠做這樣的事情:抑制具有屬性的PostSharp多播

[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; 
    } 
} 

回答

5

您可以使用MethodPointcut代替MulticastPointcut,即使用Linq-過度的反思和過濾對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); 
     } 
    } 
+0

非常好,謝謝。這是一個非常強大的工具,我的項目感覺非常乾淨,沒有所有繁瑣的INotifyPropertyChanged管道工程。 – 2010-03-07 18:57:11

0

僅供參考,我有一些問題與Sharpcrafters網站上的例子,不得不進行以下更改:

/// <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成員,但在導入它有一個前創造機會。這會導致OnPropertySet失敗,因爲this.OnPropertyChangedMethod爲空。

3

另一種簡單的方法,使用方法:

[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來刪除下劃線指示哪些屬性附接到所述方法。當然,如果運行調試器,它將跳過執行該特定方法的任何屬性。