C# 对代码gen使用反射?

C# 对代码gen使用反射?,c#,reflection,code-generation,C#,Reflection,Code Generation,我正在编写一个控制台工具来为类库中的对象生成一些C代码。我可以实际生成代码的最佳/最简单的方法是在构建库之后使用反射。它工作得很好,但这充其量只是一种随意的方法。由于生成的代码将使用库进行编译,在进行更改后,我需要构建两次解决方案以获得最终结果,等等。其中一些问题可以通过构建脚本来缓解,但对我来说,这仍然有点太麻烦了 我的问题是,对于这类事情有什么高级的最佳实践吗?据我所知,您可以使用公共编译器基础结构()之类的东西以编程方式分析现有的c源代码 不过,我觉得这很复杂,而且CCI显然只完全支持C语

我正在编写一个控制台工具来为类库中的对象生成一些C代码。我可以实际生成代码的最佳/最简单的方法是在构建库之后使用反射。它工作得很好,但这充其量只是一种随意的方法。由于生成的代码将使用库进行编译,在进行更改后,我需要构建两次解决方案以获得最终结果,等等。其中一些问题可以通过构建脚本来缓解,但对我来说,这仍然有点太麻烦了


我的问题是,对于这类事情有什么高级的最佳实践吗?

据我所知,您可以使用公共编译器基础结构()之类的东西以编程方式分析现有的c源代码

不过,我觉得这很复杂,而且CCI显然只完全支持C语言规范2。更好的策略可能是简化现有方法。

您可能希望使用,这样您只需构建一次


首先,我会阅读以确保没有使用反射就无法支持特定于语言的功能。

我不确定这样做的最佳方法,但您可以这样做

  • 作为基本dll的后期构建步骤,请运行代码生成器
  • 作为另一个生成后步骤,运行
    csc
    msbuild
    来生成生成的dll

  • 其他依赖于生成的dll的内容也需要依赖于基本dll,因此构建顺序保持正确


您是否考虑过使用T4模板来执行代码生成?看起来它现在得到了更多的宣传和关注,并且在VS2010中得到了更多的支持

本教程似乎以数据库为中心,但它可能会给您一些提示:此外,T4上最近有一个Hanselminutes

编辑:另一个好地方是StackOverflow上的T4标签:

编辑:(由asker撰写,新发展)


从VS2012开始,T4现在支持在单个步骤中对活动项目进行反射。这意味着您可以对代码进行更改,T4模板的编译输出将反映最新版本,而无需执行第二个反映/构建步骤。有了这个功能,我将此标记为已被接受的答案。

您正在做的事情非常不清楚,但似乎很清楚的是您有一些基线代码,并且基于它的一些属性,您希望生成更多的代码

所以这里的关键问题是,给定基线代码,如何提取有趣的属性,以及如何从这些属性生成代码

反射是一种将正在运行(至少已加载)的代码的属性提取到与反射用户代码相同的执行环境中的方法。反射的问题在于它只提供非常有限的一组属性,通常是类、方法的列表,或者可能是参数的名称。如果你想做的所有代码生成都可以用它来完成,那么反射就很好了。但是,如果您想要更详细地了解代码的属性,反射将无法解决这一问题

事实上,可以从中提取真正任意代码属性的唯一工件是将源代码作为字符串(否则怎么回答呢,变量名中间的add运算符和T之间的字符数是质数?)。实际上,从字符串中获得的属性通常不是很有用(请参见我刚才给出的示例:)

在过去的60年里,编译器们一直在研究如何提取有趣的程序属性,如果你忽视他们在那半个世纪里学到的东西,那你就是个十足的白痴

他们已经确定了一些相对标准的“编译器数据结构”:抽象语法树(AST)、符号表(ST)、控制流图(CFG)、数据流事实(DFF)、程序三元组、庞特分析等。 如果要分析或生成代码,最好先将其处理为标准编译器数据结构,然后再执行此工作。如果您有AST,您可以回答关于使用什么运算符和操作数的各种问题。如果您有STs,您可以回答有关定义在哪里、在哪里可见以及什么类型的问题。如果你有CFG,你可以回答关于“这个在那个之前”,“声明X依赖于什么条件”的问题。如果您有DFF,您可以确定哪些赋值会影响代码中某一点上的操作。反射永远不会提供这种IMHO,因为它总是局限于运行时系统开发人员在运行程序时愿意保留的内容。(也许有一天他们会保留所有的编译器数据结构,但这样就不会是反射;它最终只是编译器支持)

现在,在确定了感兴趣的属性之后,如何生成代码?在这里,编译人员一直非常关注机器代码的生成,以至于他们没有提供标准答案。这样做的人是程序转换社区()。这里的想法是将程序的至少一种表示形式保留为AST,并提供对匹配源代码语法的特殊支持(通过从感兴趣的代码片段构造模式匹配AST),并提供“重写”规则,有效地说,“当您看到此模式时,然后在此条件下用该模式替换它”。 通过将条件与编译器人员提供的各种属性提取机制相连接,您可以相对轻松地说出您希望得到的50年经验的支持。这种程序转换系统能够读入源代码, 进行分析和转换,通常在转换后重新生成代码

对于代码生成任务,您可以将基线代码读入AST,应用分析来确定感兴趣的属性,