3

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

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

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

4

3 回答 3

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”,它根据方法的类型(静态、虚拟、 ETC。)。

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

该代码可在 CodePlex 上找到

于 2009-10-20T12:34:01.573 回答
2

是的!

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

这是我从MSDN Expression Trees 页面中偷来的一个示例,只是为了展示它的强大功能:

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 结合起来。

于 2009-10-20T12:32:52.230 回答
1

我喜欢 Reflector 的反射发射语言插件。这使您可以反编译您知道的代码并查看制作它所需的 SRE 代码,非常有用。

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

于 2010-01-11T01:41:56.200 回答