在运行时动态覆盖一个方法,或者观察一个方法在运行时被调用?

3

我主要是一名Objective-C/Cocoa开发人员,但我正在尝试在C#.NET中实现观察者模式,具体地模仿NSKeyValueObserving协议和方法。

我已经通过手动支持来模仿NSKVO,如苹果的KVO编程指南所述(请参见http://tinyurl.com/nugolr)。由于我自己编写了setValue:forKey:方法,因此可以通过它们实现自动KVO通知。

但是,我想以某种方式在运行时动态覆盖所有属性上的自动KVO。例如,将Button.Title.set替换为:

set { 
    this.willChangeValueForKey("title");
    title = value;
    this.didChangeValueForKey("title");
}

所以,这是我的问题:

如何在运行时动态覆盖C#中的方法或属性?我已经通过使用Reflection.MethodInfo按名称获取和调用方法和属性。另外,我能观察运行时并找出何时将要/已经调用方法吗?

5个回答

1

动态元编程和面向方面的编程在C#中尚未得到强力支持。您可以查看一个名为PostSharp的免费工具 - 它允许轻松地将方面织入到围绕属性和方法调用的代码中。

您可以实现INotifyPropertyChanged接口(不使用postsharp),并且在某些情况下可以用于通知观察者属性值已更改。但是,它仍然需要每个属性实际广播更改通知 - 这通常需要特别编写以支持该通知。在纯C#中注入更改通知(而不实际更改源)并不容易。PostSharp(或其他AOP /动态代理库)使这种事情变得极其容易。


不容易?使用PostSharp,您只需在类上添加[NotifyPropertyChanged]修饰符即可。没有比这更简单的了... - Mauricio Scheffer
第二部分旨在评估没有PostSharp的通知 - 我应该澄清一下。 - LBushkin
谢谢您的回复!看了 PostSharp 的文档,似乎我必须修改现有的类。不幸的是,如果是这种情况,它并不是我正在寻找的解决方案 - 我想使用内置在 .NET 中的类来完成这个问题。 - iKenndac

0

在对这个主题进行了广泛的研究后,我发现在.NET的当前状态下,我无法完全按照自己的意愿使用它。

  • PostSharp的方法是在编译时完成的,这意味着我无法动态地将自己的实现插入到方法中。

  • Reflection.Emit允许我动态地执行此操作,但它会生成一个新的子类实例 - 我需要这样做才能使其与原始实例一起工作。

  • 如果任何现有的.NET类实际上使用了它们,INotifyPropertyChanging和INotifyPropertyChanged将是完美的选择。

...所以,目前我有点困惑。我在我的博客post上发布了更详细的内容,介绍了我正在做什么以及如何实现。希望.NET 4.0的动态调度能够帮助我!


0

我不确定你是否需要走这条路。但是,如果你想要实现方法的重写(即为该方法生成新代码?),那么使用 Emit 是可能的。在深入探究之前,我建议先探索其他任何建议。


0

0

这并没有解决动态添加跟踪代码的问题,但是阅读起来可能会很有趣:使用弱事件进行可跟踪属性

使用这些内容,您可以跟踪特定属性的更改,并更轻松地实现INotifyPropertyChanged(即跟踪所有属性的更改)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接