繁体   English   中英

Reflection.Emit与CodeDOM

[英]Reflection.Emit vs CodeDOM

使用Reflection.Emit库与CodeDOM在运行时动态生成代码有什么优缺点?

我试图在基于XML格式运行时可用元数据的系统中生成一些(相对复杂的)动态类。 我将生成扩展应用程序集中现有类的类,实现其他接口,添加方法以及覆盖虚拟和抽象成员。

我想确保在深入实现之前选择适当的技术。 有关这些不同代码生成技术如何不同的任何信息都会有所帮助。 此外,任何有关简化或简化工作的开源库的信息都将是有用的。

我认为关于CodeDOM和Reflection.Emit的关键点如下:

  • CodeDom生成C#源代码,通常在生成代码时使用,作为解决方案的一部分并在IDE中编译(例如,LINQ to SQL类,WSDL,XSD都以这种方式工作)。 在此方案中,您还可以使用部分类来自定义生成的代码。 效率较低,因为它生成C#源,然后运行编译器来解析它(再次!)并编译它。 您可以使用相对高级的构造(类似于C#表达式和语句)(如循环)生成代码。

  • Reflection.Emit生成一个IL,因此它直接生成一个程序集,该程序集也只能存储在内存中。 因此效率更高。您必须生成低级IL代码(值存储在堆栈中;循环必须使用跳转实现),因此生成更复杂的逻辑有点困难。

通常,我认为Reflection.Emit通常被认为是在运行时生成代码的首选方法,而在编译时生成代码时首选CodeDOM。 在您的场景中,它们都可能正常工作(尽管CodeDOM可能需要更高的权限,因为它实际上需要调用C#编译器,这是任何.NET安装的一部分)。

另一种选择是使用Expression 在.NET 4.0中,它允许您生成与C#表达式和语句等效的代码。 但是,它不允许您生成类。 因此,您可以将它与Reflection.Emit相结合(以生成将实现委托给使用Expression生成的代码的类)。 对于某些场景,您可能也不需要完整的类层次结构 - 通常,动态生成的委托字典(如Dictionary<string, Action>可能足够好(但当然,这取决于您的确切场景)。

针对CodeDom的代码往往更容易维护,因为您生成C#代码而不是IL(更多人可以读取C#而不是IL)。 此外,如果您的CodeDom代码出错,则会出现编译错误; 如果您生成无效的IL,则会出现致命异常或崩溃。

但是,因为CodeDom调用csc.exe编译器,所以准备使用代码要慢一些。 使用Reflection.Emit,您可以直接在内存中生成代码。

CodeDom可能适用于大多数事情; XmlSerializer和WinForms设计器使用它。

您可能想要查看ExpandoObject 但它只是.NET 4.0。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM