是否可以在.NET中的运行时修改方法体?

时间:2008-10-30 01:38:45

标签: .net reflection code-generation types

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

有什么建议吗?

我想如果我不能使用这种方法,我总是可以使用基类中的虚方法(带有属性),结合静态工厂来运行派生的动态类型 - 子类中的时间生成方法。尽管如此,这并不是那么干净。

5 个答案:

答案 0 :(得分:9)

PostSharp这是一个后编译器,它做了类似于你描述的东西,使用属性在代码中标记注入点,唯一的区别是它在编译时完成。

但是你也可以在运行时不是通过更改方法体,而是使用从ContextBoundObject派生的类,它是一个.Net类,可以拦截所有针对它的调用。这是一个描述如何使用ContextBoundObject执行AOP的MSDN Magazine article。 (查看文章中方面的.Net 部分)

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

编辑:

有一个选项可以使用.Net unmanaged profiling API来拦截方法JIT并在JIT之前替换方法体。 JustMock(Telerik)成功使用了这种技术,以模拟,静态方法,非虚方法甚至密封类。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

之前曾问过somewhat similar question(好吧,所以我的解决方案有些类似)。 PostSharp已被提及,但在研究问题时我发现这个非常适用LinFu article on CodeProject

答案 4 :(得分:0)

您打算为任意类型执行此操作吗?我认为没有给出你将使用属性装饰方法。

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

一般来说,除非您在运行时创建代码文件并编译动态程序集,否则您无法完成的工作。可能会有更多实用的OO原则和模式用于实现接近相同的结果。