是否有工具可以使用Reflection.Emit简化工作?

时间:2009-10-20 12:26:44

标签: .net reflection.emit

我需要动态生成一些类型。生成的类型有几个方法,构造函数,实现接口并定义静态构造函数。有没有可以帮助完成任务的工具?

我知道Reflector的this插件,但它只在方法级别有用,而我必须生成一个完整的类型。

Run#,但是它处于pre-alpha状态,此外,我想要一个独立的工具在离线模式下工作,这样我就可以将reflection.emit指令复制粘贴到生产代码中。

3 个答案:

答案 0 :(得分:3)

好吧,我个人已经在ILGenerator类上创建了与操作码同名的扩展方法,并使用正确的参数,这样我就不必一直查找文档了。这些扩展方法也返回它被调用的生成器对象,因此我可以进行调用链接。

例如,要实现ToString方法,我可以这样做:

var il = method.GetILGenerator();
il
    .ldarg_0()
    .ldfld(nameField)
    .ret();

我还创建了一个名为IL的类似类,它具有返回IL.Element对象的方法,在最终发出代码之前,我可以将其收集到集合或类似对象中,操作等。这允许我创建“代码生成器”而不仅仅是“代码发射器”。微妙的区别,但我发现“给我可以发出的代码”比“将代码发送到这个ILGenerator”更有用。

因此,我可以这样做:

IL.Element[] il = new IL.Element[] {
    IL.ldarg_0(),
    IL.ldfld(nameField),
    IL.ret()
};

然后:

method.GetILGenerator.Emit(il); // also an extension method

当然,我添加了一些额外的扩展方法,使我更容易发出代码,例如“call_smart”,它根据方法的类型确定要发出的调用指令(静态) ,虚拟等。)。

除此之外,我不知道任何其他工具,所以也许我没有真正回答你的问题。

The code is available on CodePlex

答案 1 :(得分:2)

是!

System.Linq.Expressions命名空间(在.NET 3.5中)通过使用抽象表达式树而不是原始IL,极大地简化了动态生成代码。

以下是我从MSDN Expression Trees page偷来的一个例子,只是为了展示它的力量:

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 });

你不能创建类型,只能创建函数,所以如果你想创建整个类,你将不得不将它与Reflection.Emit结合起来。

答案 2 :(得分:1)

我喜欢Reflector的反射发射语言插件。这使您可以将您熟悉的代码整形,并查看制作它所需的SRE代码,非常有用。

http://www.codeplex.com/wikipage?ProjectName=reflectoraddins&title=ReflectionEmitLanguage&referringTitle=Home