c# on nested 属性 更改跟踪
c# on nested property change tracking
我有一个泛型 class,它带有一个参数,代表第三方 DLL 的一个元素,用于序列化 T 类对象。我想要做的是将 'Dirty' 映射添加到我的 class 并在我的元素的嵌套属性之一发生更改时延迟触发它。
是否可以在访问 属性 时捕获请求并确定 属性 发生了什么变化?如果正在执行 SET 我可以记录 sub-属性 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' 的高级示例。您可以看到我需要如何递归我的操作,因为并非所有内容都是原始的。我有一个管理级别 class 记录所有这些 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()
{
}
}
还有一个小的class我以后会变成测试方法..
public class DoThing
{
public DoThing()
{
ResourceSerializer<Person> person = new ResourceSerializer<Person>();
person.Element.Age = 13; // catch this and mark 'Age' as dirty.
}
}
没有自定义 setter 不,没有什么可做的。
您尝试做的通常模式是实现 INotifyPropertyChanged 接口,该接口是为需要跟踪和通知其属性更改的 classes(或结构)精确创建的。
如果你像我一样懒惰,我会创建一个分析器,它在我的应用程序开始时扫描我所有的 classes,这些 classes 被标记为一个属性并且所有属性都创建为虚拟,然后使用codedom 我会创建一个新的 class,它将继承找到的 class 并实现 INotifyPropertyChanged,然后您可以拥有一个通用工厂,其中 returns 这些新 class 的实例es 当泛型调用的类型是已知的注册类型时。
我之前在 classes 中使用过它,我希望它具有远程属性,只是标记了 class 并且我的扫描系统重写了 getter/setter 以进行远程调用显然,最后的概念是一样的。
开始时需要做很多工作,但如果您有大量 classes,那么与在所有 classes 上实施 INotifyPropertyChanged 相比,编写的代码要少得多。
我有一个泛型 class,它带有一个参数,代表第三方 DLL 的一个元素,用于序列化 T 类对象。我想要做的是将 'Dirty' 映射添加到我的 class 并在我的元素的嵌套属性之一发生更改时延迟触发它。
是否可以在访问 属性 时捕获请求并确定 属性 发生了什么变化?如果正在执行 SET 我可以记录 sub-属性 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' 的高级示例。您可以看到我需要如何递归我的操作,因为并非所有内容都是原始的。我有一个管理级别 class 记录所有这些 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()
{
}
}
还有一个小的class我以后会变成测试方法..
public class DoThing
{
public DoThing()
{
ResourceSerializer<Person> person = new ResourceSerializer<Person>();
person.Element.Age = 13; // catch this and mark 'Age' as dirty.
}
}
没有自定义 setter 不,没有什么可做的。
您尝试做的通常模式是实现 INotifyPropertyChanged 接口,该接口是为需要跟踪和通知其属性更改的 classes(或结构)精确创建的。
如果你像我一样懒惰,我会创建一个分析器,它在我的应用程序开始时扫描我所有的 classes,这些 classes 被标记为一个属性并且所有属性都创建为虚拟,然后使用codedom 我会创建一个新的 class,它将继承找到的 class 并实现 INotifyPropertyChanged,然后您可以拥有一个通用工厂,其中 returns 这些新 class 的实例es 当泛型调用的类型是已知的注册类型时。
我之前在 classes 中使用过它,我希望它具有远程属性,只是标记了 class 并且我的扫描系统重写了 getter/setter 以进行远程调用显然,最后的概念是一样的。
开始时需要做很多工作,但如果您有大量 classes,那么与在所有 classes 上实施 INotifyPropertyChanged 相比,编写的代码要少得多。