12

我知道(理论上)可以在运行时创建新类型,但是是否可以在运行时修改现有类型的方法体?我的计划(如果我可以让它工作的话)是用自定义属性标记方法,然后在运行时搜索具有该属性的方法,并将我自己的一些代码插入到方法体中。

有什么建议么?

我想如果我不能让这种方法发挥作用,我总是可以使用基类中的虚拟方法(带有属性),结合静态工厂来使用我的运行时生成的方法生成派生的动态类型在儿童班。不过,这用起来不太干净。

4

5 回答 5

9

PostSharp是一个后编译器,与您描述的内容类似,使用属性在代码中标记注入点,唯一的区别是它在编译时执行。

但是您也可以在运行时执行此操作,而不是通过更改方法主体,而是使用派生自ContextBoundObject的类,这是一个 .Net 类,可让您拦截对其进行的所有调用。这是一篇MSDN 杂志文章,描述了如何使用 ContextBoundObject 进行 AOP。(检查文章.Net部分中的方面)

作为第三种选择,您可以将动态代码生成(Reflection.Emit 或 CodeDom)与属性和虚拟方法结合使用,以动态生成可以插入代码的派生类,但这是最痛苦的方法。

编辑:

还有第四个选项是使用.Net 非托管分析 API来拦截方法 JIT-ing 并在 JIT-ing 之前替换方法主体。JustMock (Telerik) 成功地使用这种技术来模拟、静态方法、非虚拟方法甚至密封类。

于 2008-10-30T02:02:08.127 回答
3

您无法在运行时修改现有方法,但您可以使用 Code DOM 动态创建一个并执行该方法。或者,您可以将代码串连接在一起,然后在内存中编译并运行它。

我自己完成了后者(我允许在内存中编译和执行的自定义 C# 代码的应用程序,运行时)。

于 2008-10-30T01:49:31.287 回答
2

如果您希望在调用前或调用后添加方面,请查看 PostSharp:http ://www.postsharp.org/

于 2008-10-30T01:52:26.850 回答
1

之前提出了一个有点相似的问题(好吧,所以我的解决方案有点相似)。 PostSharp已经被提及,但在 CodeProject 上也有这篇非常适用的 LinFu 文章,我在研究这个问题时发现很有趣。

于 2008-10-30T03:51:00.997 回答
0

您打算对任意类型执行此操作吗?我想不会因为您要使用属性来装饰方法。

鉴于此,我认为更好的方法是在超类中为您的类型定义抽象方法。超类上的方法可以容纳样板方法代码,并通过抽象方法委托给具体实现,以实现该方法的各个类型的行为。

一般来说,除非您在运行时创建代码文件和编译动态程序集,否则您想要做的事情是无法完成的。您可以使用更多实用的 OO 原则和模式来实现接近相同的结果。

于 2008-10-30T01:46:49.000 回答