2011-05-21 180 views
7

我正在創建一個框架,我在其中提供基類的過程中,框架的實現者將從基類繼承並提供其他屬性和方法。在基類中,我希望有一種觀察屬性值何時更改的方法。該屬性可以來自基類或任何子類。我知道通過反思,我可以確定任何實例的屬性列表,但有沒有一種方法可以跟蹤屬性更改值?C# - 攔截屬性更改

這是我所說的一個非常簡單的例子:

public class BaseClass 
{ 
    public string BaseClassProperty { get; set; } 

    public void DoSomethingWhenEitherPropertyGetsChanged() 
    { 

    } 
} 

public class SubClass : BaseClass 
{ 
    public string SubClassProperty { get; set; } 
} 

我能做些什麼有DoSomethingWhenEitherPropertyGetsChanged當任一屬性都有它的價值變化得到執行。

+0

即使在基類中,你將不得不調用'DoSomethingWhenEitherPropertyGetsChanged()'在你的屬性設置,所以你可以做同樣的呼叫的制定者子類的屬性。 – 2011-05-21 00:45:29

+0

對於任何有興趣實現攔截器的人來說,看一看[TinyInterceptor](https://github.com/Jalalx/TinyInterceptor) – Jalal 2016-07-25 19:07:41

回答

4

您可以使用notifypropertyweaver來實現此目的。它確實是你想要的。這裏有一個鏈接:

從開源主頁:

使用IL織(通過http://www.mono-project.com/Cecil)注入INotifyPropertyChanged的代碼到性能。

  • 任何屬性需要
  • 沒有引用所需
  • 否基類需要
  • 支持.NET 3.5,.NET 4,Silverlight 3中,Silverlight 4中,的Silverlight 5和Windows Phone 7
  • 支架客戶資料模式
+0

謝謝!經過快速測試,這似乎正是我所需要的! – 2011-05-21 01:44:24

+0

很高興我能幫到你。這是一個非常酷的項目。 – 2011-05-21 01:50:06

+0

現在沒有找到:( – kaspartus 2013-11-12 07:27:05

3

我可能會使用Postsharp並創建一個將攔截代碼注入所有公共屬性的繼承屬性。將該屬性標記爲繼承,也應該將其自動附加到所有子類。

+0

你是說應該在'BaseClass'上創建一個屬性來攔截setter方法在基類的所有屬性以及任何繼承類? – 2011-05-21 01:17:35

+0

Postsharp定義了一些基本上允許您將代碼注入各種方法的屬性。 – ChrisWue 2011-05-21 07:40:26

0

最好的選擇是CrisWue推薦的方法,並使用postsharp或其他後處理器在您的屬性中注入行爲。除此之外,我認爲您需要在屬性中手動調用DoSomethingWhenEitherPropertyGetsChanged()。

如果您正在創建一個由您或您的組織以外的人使用的庫,後處理器可能不是正確的路,因爲它將第三方工具作爲構建過程的另一個要求。

1

我寫了我自己的想法,您的要求,但我不知道它是否適合您的需求。 INotifyProperty的改變是你可以研究的東西,但是我不太喜歡它,因爲它就像接連接Speghetti。雖然這可能會給你一些創意。

這樣做,可以讓您使用ObservableObject作爲您的所有屬性類型。通過這樣做,每個屬性都會有一個可以連接到的ObjectChanged事件。 con(s)是你必須初始化構造函數中的所有屬性,以防止代碼中某處出現NullReferenceException。

本例使用三個類。

  • ObservableObject.cs
  • Employee.cs
  • Program.cs的

ObservableObject.cs

//----------------------------------------------------------------------------- 
    // <copyright file="ObservableObject.cs" company="DCOM Productions"> 
    //  Copyright (c) DCOM Productions. All rights reserved. 
    // </copyright> 
    //----------------------------------------------------------------------------- 

    namespace PropertyChangedEventExample { 
     using System; 

     public class ObservableObject : Object { 
      /// <summary> 
      /// Expose the default constructor 
      /// </summary> 
      public ObservableObject() { 
       // No default implementation 
      } 

      private object m_Object = null; 
      /// <summary> 
      /// Base object 
      /// </summary> 
      public object Object { 
       get { 
        return m_Object; 
       } 
       set { 
        if (m_Object != value) { 
         m_Object = value; 
         OnObjectChanged(this, EventArgs.Empty); 
        } 
       } 
      } 

      /// <summary> 
      /// Triggered when the value of this object has changed. 
      /// </summary> 
      public event System.EventHandler<EventArgs> ObjectChanged; 
      /// <summary> 
      /// EventHandler wire-up 
      /// </summary> 
      protected virtual void OnObjectChanged(object sender, System.EventArgs e) { 
       if (ObjectChanged != null) { 
        ObjectChanged(sender, e); 
       } 
      } 

      /// <summary> 
      /// Gets the value 
      /// </summary> 
      public object Get() { 
       return this.Object; 
      } 

      /// <summary> 
      /// Sets the value 
      /// </summary> 
      public void Set(object value) { 
       this.Object = value; 
      } 
     } 
    } 

Employee.cs

//----------------------------------------------------------------------------- 
    // <copyright file="Employee.cs" company="DCOM Productions"> 
    //  Copyright (c) DCOM Productions. All rights reserved. 
    // </copyright> 
    //----------------------------------------------------------------------------- 

    namespace PropertyChangedEventExample { 
     using System; 

     public class Employee { 
      /// <summary> 
      /// Expose default constructor 
      /// </summary> 
      public Employee() { 
       Name = new ObservableObject(); 
      } 

      /// <summary> 
      /// Gets or sets the name 
      /// </summary> 
      public ObservableObject Name { 
       get; 
       set; 
      } 
     } 
    } 

Program.cs的

//----------------------------------------------------------------------------- 
    // <copyright file="Program.cs" company="DCOM Productions"> 
    //  Copyright (c) DCOM Productions. All rights reserved. 
    // </copyright> 
    //----------------------------------------------------------------------------- 

    namespace PropertyChangedEventExample { 
     using System; 

     class Program { 
      static void Main(string[] args) { 
       Employee employee = new Employee(); 
       employee.Name.Set("David"); 
       employee.Name.ObjectChanged += new EventHandler<EventArgs>(Name_ObjectChanged); 
       employee.Name.Set("Dave"); 
       Console.ReadKey(true); 
      } 

      static void Name_ObjectChanged(object sender, EventArgs e) { 
       ObservableObject employee = sender as ObservableObject; 
       Console.WriteLine("Name changed to {0}", employee.Get()); 
      } 
     } 
    }