12

我正在研究与语言无关(至少在一定范围内)源代码生成的System.CodeDom命名空间CodeDom,并且我发现了一些不鼓励使用.

我认为这篇早期博文中描述的一些遗漏现在已经得到修复,而且CodeDom似乎没有提供创建switch语句的方法这一事实仍然允许 - 性能降低?- 解决方法,而不用丑化生成类型的公共接口。这同样适用于自动 C# 属性集合初始值设定项

但是,其他遗漏无法真正解决,例如无法创建终结器无法声明扩展方法缺乏对泛型引用类型约束的直接支持

请注意,使用CodeSnippetTypeMember或通过任何其他方式注入文字源代码片段的建议解决方案并不令人满意,因为它们不是语言独立的 - 从而消除了使用CodeDom而不是String.Format文字代码片段的全部意义。

最后,在这个 SO 问题中甚至建议“CodeDom 是失败的,而表达式树(或者更确切地说是“语句”树)是前进的方向”——尽管没有任何解释如何从表达式树中实际获取任何源代码(除了不能用表达式树声明类的限制之外。

CodeDom 是否仍然是生成源代码的首选方法,或者当前的 BCL 是否提供了一个我没有想到的名称的模糊替换?

4

2 回答 2

4

我认为 CodeDom 仍然是当今 BCL 中最好的解决方案,但是:Roslyn 项目已经走得很远,并且已经推出了几个 CTP。目标是将编译器作为服务提供,它将通过简单的 API 实现代码生成和代码检查场景。

看看它,如果您可以为您的项目使用预发布位:Roslyn CTP。这是一个相关的(虽然已经过时,但仍然有一些很好的信息)StackOverflow 问题:Microsoft Roslyn vs. CodeDom。最后,一篇关于使用 Roslyn 进行代码生成的文章:Code Generation in .NET with the Roslyn CTP

于 2013-02-10T11:13:14.107 回答
3

不,CodeDom 可用于生成要执行的代码。它生成文本的能力只是一个偶然的副产品,因为编译器需要文本而需要它。如果你真的关心文本,那么有很多理由不喜欢 CodeDom,而且框架中没有任何东西可以帮助你。

其他解决方案同样侧重于生成可执行代码。Reflection.Emit 生成 IL(.NET 中的通用语言),但没有提供简单的反编译方法,尽管任何体面的反编译器(ILSpy、Reflector 等)都可以提供帮助。Linq.Expressions 是纯可执行代码,通常对生成完整程序没有用处。Roslyn 非常倾向于已经拥有文本。

最好的前进方式可能是弃用您对使用特定语言的文本的要求。所有 .NET 编译器都具有相同类型的输出,它们都编译为 IL。这使得将您的选择限制为一种语言成为一种可行的方法。从您的问题中不清楚这是否是一个合理的限制。这似乎是一个常见的选择,我想不出一个曾经试图解决 CodeDom 限制的项目。codeplex.com 上提供的以 CodeDom 为目标的项目类型试图尽量减少使用 CodeDom 的代码所需的冗长带来的痛苦。

于 2013-02-10T11:54:26.267 回答