【问题标题】:c# on nested property change trackingc# 关于嵌套属性更改跟踪
【发布时间】:2016-05-11 17:59:30
【问题描述】:

我有一个带有单个参数的通用类,它代表第三方 DLL 的元素,用于 T 类对象的序列化。我想做的是向我的类添加一个“脏”映射,并在我的元素的嵌套属性之一发生更改时懒惰地触发它。

是否可以在访问属性时捕获请求并识别正在更改的属性?如果正在执行 SET,我可以记录子属性 P 现在是脏的并且需要保存?或者至少有一个位表明某事发生了变化?

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

'Base' 的一个高级示例。您可以看到我需要如何递归我的操作,因为并非所有内容都是原始的。我有一个记录所有这些 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.
    }
  }

【问题讨论】:

    标签: c# reflection propertychangelistener nested-properties


    【解决方案1】:

    如果没有自定义设置器 no,就没有什么可做的。

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

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

    我之前将它用于我想要具有远程属性的类,只是标记了该类,我的扫描系统重写了 getter/setter 以透明地进行远程调用,最后的概念是相同的。

    一开始需要做很多工作,但是如果您有大量的类,那么编写的代码将比在所有类上实现 INotifyPropertyChanged 少得多。

    【讨论】:

    • 是的,我引用的 dll 有数百个类,它们的属性都不是虚拟的。我希望能够反思地完成这一切。
    • 那么你最好的办法是创建一个像我描述的那样的系统,用 codedom 动态地重新创建类类型。
    • 哎呀,没有阅读有关虚拟位的信息...如果这是您的情况,那么也许使用 new 关键字可以做到,只需记住读取和写入基本属性即可。
    猜你喜欢
    • 2016-05-22
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多