Reflection.Emit的VS codeDOMEmit、Reflection、codeDOM、VS

2023-09-02 01:53:11 作者:美的惊动了如来佛

有哪些优点/缺点,使用了Reflection.Emit的库与codeDOM动态生成code运行时?

我想产生一些(相对复杂),动态类的系统的基础上在运行时可用XML形式的元数据。我将生成类,扩展现有的类中的应用程序组件,实现额外​​的接口,添加方法,和压倒一切的虚拟和抽象成员。

I am trying to generate some (relatively complicated) dynamic classes in a system based on metadata available at runtime in XML form. I will be generating classes that extend existing classes in the application assembly, implementing additional interfaces, adding methods, and overriding virtual and abstract members.

我要确保我选择合适的技术之前,我太深入实施。关于如何将这些不同的code代技术不同,所有信息将是有益的。此外,开源库,简化或优化工作枯萎或者API的任何信息将是有用的。

I want to make sure I select the appropriate technique before I get too deep into the implementation. Any information about how these different code-generation techniques differ would be helpful. Also, any information on open-source libraries that simplify or streamline working wither either API would be useful as well.

推荐答案

我想codeDOM和Reflection.Emit的关键点如下:

I think the key points about CodeDOM and Reflection.Emit are following:

codeDOM 生成C#源$ C ​​$ c和产生code时,通常被用来包含作为解决方案的一部分,并在IDE编译(例如,LINQ to SQL类,WSDL,XSD所有的工作这种方式)。在这种情况下,你也可以使用部分类来定制生成code。这是效率较低,因为它生成C#源代码,然后运行编译器(又来了!)对其进行解析和编译。您可以使用较高级别的结构(类似于C#EX pressions和放大器;语句)产生code,如循环

CodeDom generates C# source code and is usually used when generating code to be included as part of a solution and compiled in the IDE (for example, LINQ to SQL classes, WSDL, XSD all work this way). In this scenario you can also use partial classes to customize the generated code. It is less efficient, because it generates C# source and then runs the compiler to parse it (again!) and compile it. You can generate code using relatively high-level constructs (similar to C# expressions & statements) such as loops.

Reflection.Emit的产生白细胞介素,因此直接产生一个可存储也只在内存中的程序集。其结果是一个很大的efficient.You不得不产生低水平IL code(值存储在堆栈;循环已经用跳跃来实现),因此产生的任何更复杂的逻辑是有点难度

Reflection.Emit generates an IL so it directly produces an assembly that can be also stored only in memory. As a result is a lot more efficient.You have to generate low-level IL code (values are stored on stack; looping has to be implemented using jumps), so generating any more complicated logic is a bit difficult.

在一般情况下,我认为Reflection.Emit的通常被认为是pferred的方式来产生code运行时的$ P $,而codeDOM是preferred产生code编译期前,当时间。在您的情况,他们都可能会正常工作(虽然codeDOM可能需要更高的权限,因为它实际上需要调用C#编译器,这是任何.NET安装的一部分)。

In general, I think that Reflection.Emit is usually considered as the preferred way to generate code at runtime, while CodeDOM is preferred when generating code before compile-time. In your scenario, both of them would probably work fine (though CodeDOM may need higher-privileges, because it actually needs to invoke C# compiler, which is a part of any .NET installation).

另一种选择是使用Ex$p$pssion类。在.NET 4.0中它可以让你产生$ C相当于C#的前pressions和语句$ C。但是,它不允许你生成一个类。所以,你可以与Reflection.Emit的结合起来(生成类授权使用生成的实现,以code 防爆pression )。在某些情况下,你也未必真的需要一个完整的类层次结构 - 动态生成的代表,如词典&LT往往一本字典,字符串,作用> 可能是不够好(当然,它取决于你的具体情况下)。

Another option would be to use the Expression class. In .NET 4.0 it allows you to generate code equivalent to C# expressions and statements. However, it doesn't allow you to generate a classes. So, you may be able to combine this with Reflection.Emit (to generate classes that delegate implementation to code generated using Expression). For some scenarios you also may not really need a full class hierarchy - often a dictionary of dynamically generated delegates such as Dictionary<string, Action> could be good enough (but of course, it depends on your exact scenario).