Are there tools to ease the work with Reflection.Emit?
I need to dynamically generate some types. The generated type has several methods, constructors, implements an interface and defines the static constructor. Is there a tool tha开发者_运维问答t can help with the task?
I am aware of this plugin for Reflector, yet it is only useful on the method level, while I have to generate a whole type.
There is Run#, but it is in pre-alpha and besides, I would like a standalone tool to work in offline mode, so that I can copy-paste the reflection.emit instructions into the production code.
Well, personally I have created extension methods on the ILGenerator
class with the same names as the opcodes, with the right parameters, so that I don't have to look up the documentation all the time. These extension methods also return the generator object it was invoked on, so I can do call chaining.
For instance, to implement a ToString method, I could do this:
var il = method.GetILGenerator();
il
.ldarg_0()
.ldfld(nameField)
.ret();
I've also created a similar class, named IL, that has methods that return an IL.Element object, which I can collect into a collection or similar, manipulate, etc. before finally emitting the code. This allows me to create "code producers" and not just "code emitters". Subtle difference, but I've found the "give me the code I can emit" has been more useful than "emit the code into this ILGenerator".
Thus, I could do this:
IL.Element[] il = new IL.Element[] {
IL.ldarg_0(),
IL.ldfld(nameField),
IL.ret()
};
and then:
method.GetILGenerator.Emit(il); // also an extension method
Of course, I've added some extra extension methods that makes it easier for me to emit code as well, such as "call_smart", that figures out which of the call instructions to emit based on the type of method (static, virtual, etc.).
Other than that, I don't know of any other tools, so perhaps I didn't really answer your question.
The code is available on CodePlex.
Yes!
There's the System.Linq.Expressions namespace (in .NET 3.5) that greatly simplifies generating code on the fly, by using abstract expression trees instead of raw IL.
Here's an example I've stolen from the MSDN Expression Trees page, just to demonstrate its power:
ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
Expression<Func<int, bool>> lambda1 =
Expression.Lambda<Func<int, bool>>(
numLessThanFive,
new ParameterExpression[] { numParam });
You can't create types though, only functions, so if you want to create whole classes, you will have to combine this with Reflection.Emit unfortunately.
I like the reflection emit language plug in for Reflector. This allows you to decomplie code you know and see the SRE code needed to make it, extremely useful.
http://www.codeplex.com/wikipage?ProjectName=reflectoraddins&title=ReflectionEmitLanguage&referringTitle=Home
精彩评论