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

发布于 2024-08-08 19:08:17 字数 428 浏览 1 评论 0原文

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

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

Run#,但它处于预测试阶段,此外,我想要一个独立工具可以在离线模式下工作,这样我就可以将 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 that 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

后来的我们 2024-08-15 19:08:17

好吧,我个人在 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”,它可以确定要发出哪些调用指令关于方法的类型(静态、虚拟等)。

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

代码可在 CodePlex 上获取

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.

人│生佛魔见 2024-08-15 19:08:17

是的!

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

这是我从 MSDN 表达式树页面 窃取的示例,只是为了展示它的强大功能:

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

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.

残月升风 2024-08-15 19:08:17

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

http://www.codeplex.com/wikipage?ProjectName= Reflectoraddins&title=ReflectionEmitLanguage&referringTitle=主页

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文