Is it possible to modify a method body at run-time

2020-02-28 03:40发布

问题:

I know that it is possible (in theory) to create a new type at run-time, but is it possible to modify a method body of an existing type at run-time? My plan (if I can get this to work) is to tag up methods with a custom attribute, and then at run-time search for methods with the attribute, and insert some of my own code into the method body.

Any suggestions?

I suppose if I can't get that approach to work, I could always go with a virtual method in a base class (with the attributes), combined with a static factory to spit out a derived dynamic type with my run-time generated method in the child class. This would not be quite as clean to use though.

回答1:

PostSharp which is an aftercompiler, does something similar to what you describe, using attributes to mark injection points in the code, only difference is that it does it at compile time.

But you can also do it at runtime not by changing method bodies but by using classes derived from ContextBoundObject which is a .Net class that lets you intercept all the calls made against it. Here is a MSDN Magazine article describing how to do AOP using ContextBoundObject. (Check the aspects in .Net part of the article)

And as a third option you can use dynamic code generation (Reflection.Emit or CodeDom) in combination with attributes and virtual methods to dynamically generate derived classes where you can insert your code, but this is the most painful way to do it.

Edit:

There's a forth option to use .Net unmanaged profiling API to intercept method JIT-ing and replace method bodies ahead of JIT-ing. This technique is sucessfully used by JustMock (Telerik) in order to mock, static methods, non virtual methods and even sealed classes.



回答2:

You cannot modify an existing method at runtime, but you can create one with Code DOM on the fly and execute that. Or, you could concat together strings of code, and compile it in memory and run that.

I've done the latter myself (an app I had allowed custom C# code that was compiled and executed in memory, runtime).



回答3:

If you are looking to add aspects pre or post invocation, take a look at PostSharp: http://www.postsharp.org/



回答4:

A somewhat similar question was asked earlier (okay, so my solution was somewhat similar). PostSharp has already been mentioned but there is also this very applicable LinFu article on CodeProject I found interesting while researching the problem.



回答5:

Are you planning to do this for arbitrary types? I would suppose not given that you are going to decorate the methods with an attribute.

Given that, I would think the better approach would be to define abstract methods in a super class for your types. A method on the super class can house the boiler-plate method code, and delegate to the concrete implementations via the abstract methods for the individual type's behavior of that method.

Generally speaking though, unless you get into create code files and compiling dynamic assemblies at runtime, what you are looking to do can't be done. There are likely far more practical OO principles and patterns you can use to achieve close to the same result.