我主要是Objective-C / Cocoa开发人员,但我正在尝试在C#.NET中实现Observer模式,特别是模仿NSKeyValueObserving协议和方法。
我已经使用手动支持模仿NSKVO,如Apple的KVO编程指南(参见http://tinyurl.com/nugolr)中所述。由于我自己编写了setValue:forKey:方法,我可以通过那里实现自动KVO通知。
但是,我想通过在运行时动态覆盖它们来以某种方式在所有属性上实现自动KVO。例如,将Button.Title.set替换为:
set {
this.willChangeValueForKey("title");
title = value;
this.didChangeValueForKey("title");
}
所以,这是我的问题:
如何在C#中动态覆盖运行时的方法或属性?我已经得到了使用Reflection.MethodInfo按名称获取和调用方法和属性。或者,我可以观察运行时并找出何时调用方法?
答案 0 :(得分:1)
C#中尚未强烈支持动态元编程和面向方面编程。您可以做的是查看一个名为PostSharp的免费工具 - 它允许支持将属性和方法调用中的方面编织到您的代码中。
您可以实现INotifyPropertyChanged接口(不带postharp),并且可以在某些上下文中使用它来通知观察者属性的值已更改。但是,它仍然要求每个属性实际广播更改通知 - 这通常要求对其进行专门编码以支持更改通知。在直接C#中,向现有代码注入更改通知(而不实际更改源代码)并不容易。 PostSharp(其他其他AOP /动态代理库)使这种事情变得更加容易。
答案 1 :(得分:0)
我不确定你是否需要走这条路。但是,如果你想实现方法的覆盖(即为方法生成新代码?),那么可以使用Emit。在潜入深水之前,我会先探索其他任何建议。
答案 2 :(得分:0)
您正在寻找INotifyPropertyChanged。您可以动态实现using PostSharp,Castle DynamicProxy或任何其他代理库。
答案 3 :(得分:0)
这并不能解决必须动态添加跟踪代码的问题,但阅读起来很有意思:Trackable Properties with Weak Events
使用这些内容,您可以跟踪特定属性的更改,并且更容易实现INotifyPropertyChanged
(即跟踪对所有属性的更改)。
答案 4 :(得分:0)
在对这个主题进行广泛的研究之后,我似乎无法完全按照我目前的状态做.NET。
PostSharp的方法是在编译时完成的,这意味着我无法动态地将自己的实现插入到方法中。
Reflection.Emit允许我动态地执行此操作,但它会生成创建的子类的新实例 - 我需要这样做,以便它适用于原始实例。
如果任何现有的.NET类实际使用它们,INotifyPropertyChanging和INotifyPropertyChanged将是完美的。
...所以,此刻我有点卡住了。我已经在我的博客上的post中更详细地介绍了我正在做什么以及我想要实现的目标。希望.NET 4.0的动态调度能有所帮助!