我需要动态生成一些类型。生成的类型有几个方法,构造函数,实现接口并定义静态构造函数。有没有可以帮助完成任务的工具?
我知道Reflector的this插件,但它只在方法级别有用,而我必须生成一个完整的类型。
有Run#,但是它处于pre-alpha状态,此外,我想要一个独立的工具在离线模式下工作,这样我就可以将reflection.emit指令复制粘贴到生产代码中。
答案 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”,它根据方法的类型确定要发出的调用指令(静态) ,虚拟等。)。
除此之外,我不知道任何其他工具,所以也许我没有真正回答你的问题。
答案 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代码,非常有用。