c#嵌套属性更改跟踪

时间:2016-05-11 17:59:31

标签: c# reflection propertychangelistener nested-properties

我有一个带有单个参数的泛型类,它表示第三方DLL的元素,用于序列化T类对象。我想要做的是在我的类中添加一个'Dirty'映射,并在我的Element的嵌套属性之一被更改时懒惰地触发它。

是否有可能在访问该属性时捕获请求并确定哪些属性正在发生变化?如果正在执行SET,我可以记录该子属性P现在是脏的并且需要保存吗?或者至少一个指示SOMETHING已经改变的位?

  public class ResourceSerializer<T>
  where T : Base, new()
  {
   T element;
   Dictionary<String,Boolean> dirtyMap;

   public T Element { get { return this.getElement(); } }
   public Boolean IsDirty { get; private set; }

   public ResourceSerializer()
   {
     dirtyMap = new Dictionary<string,bool>();
     element = new T();
     // code to reflect back upon T's Properties and build out the dirtyMap. 
     // I already can do this I just omitted it.
     // in my Person example there would be keys:  'FirstName', 'LastName', 'Age', 'Gender', 'PrimaryAddress'
    }


   // how can I call this programmatically?
   void flagDirty(String property)
   {
     dirtyMap[property] = true;
     this.IsDirty = true;
   }
   T getElement()
   {
     // In case I need to do a thing before returning the element. 
     // Not relevant to the question at hand.
     return this.element;
   }
 }

'基础'的一个先进的例子。您可以看到我需要如何递归我的行为,因为并非所有事情都是原始的。我有一个管理器级别类,它记录所有这些ResourceSerializer对象。

 public class Base
 {
   public Base()
   {

   }
 }
 public enum gender
 {
   Male,
   Female,
   Other,
   Unspecified,
 }
  public class Address : Base
 {
   public String Street { get; set; }
   public String State { get; set; }
   public String Zip { get; set; }
   public Address() : base()
   {

   }
 }
 public class Person : Base
 {
   public String FirstName { get; set; }
   public String LastName { get; set; }
   public Int16 Age { get; set; }
   public gender Gender { get; set; }
   public Address PrimaryAddress { get; set; }
   public Person() : base()
   {

   }
 }
 public class Patient : Person
 {
   public Person PrimaryContact { get; set; }
   public Patient() : base()
   {

   }
 }

和一个小班我后来会变成一种测试方法..

  public class DoThing
  {
    public DoThing()
    {
      ResourceSerializer<Person> person = new ResourceSerializer<Person>();
      person.Element.Age = 13; // catch this and mark 'Age' as dirty.
    }
  }

1 个答案:

答案 0 :(得分:0)

如果没有自定义设置器,则无需执行此操作。

您尝试做的通常模式是实现INotifyPropertyChanged接口,该接口是为需要跟踪和通知其属性更改的类(或结构)精确创建的。

如果你像我一样懒,我会创建一个分析器,在我的应用程序开始时扫描所有我的类,这些类被标记为属性并且所有属性都被创建为虚拟,然后使用codedom我将创建一个新类它将继承自找到的类并实现INotifyPropertyChanged,然后您可以拥有一个通用工厂,当通用调用的类型是已知的注册类型时,它返回这些新类的实例。

之前我曾经使用过这个类,我想拥有远程属性,只是标记了类,我的扫描系统重写了getter / setter来透明地进行远程调用,最后的概念是相同的。

一开始就做了很多工作,但是如果你有很多课程,那么编写的代码要比在所有课程中实现INotifyPropertyChanged要少得多。