在C#中基于条件编译符号生成代码文件的最简单方法是什么?

时间:2013-06-07 20:54:40

标签: c# text-parsing codedom conditional-compilation

我正在制作一个Nuget包,需要为每个MVC版本和每个.NET版本输出一个代码版本。但是,出于显而易见的可维护性原因,我决定在同一源文件中使用条件编译常量。

我想要做的是找到一种方法来使用适当的逻辑替换编译常量所包围的所有部分,因此只保留适当的代码。例如:

    var alwaysExists = 1;
    #if !MVC2
            this.For<System.Web.Mvc.IFilterProvider>()
                .Singleton()
                .Use<FilterProvider>();
    #endif

    #if NET35
            var someVariable = 100;
    #else
            var someVariable = 200;
    #endif

在上面的代码块中,如果传入的符号是MVC4, NET40,我想用

生成一个文本文件
        var alwaysExists = 1;
        this.For<System.Web.Mvc.IFilterProvider>()
            .Singleton()
            .Use<FilterProvider>();
        var someVariable = 200;

如果传入的符号为MVC2, NET35,则文本文件应为

        var alwaysExists = 1;
        var someVariable = 100;

该方法需要支持所有逻辑方法,例如if, else, if !。它需要有.cs(文本)文件输入和.cs(文本)文件输出。

我想到了一种使用正则表达式和一些自定义代码实现这一目标的方法,但在我走这条路之前,我希望看看是否有更简单的方法。

是否有一个命令行实用程序,库或内置于.NET框架中的内容可以实现此目的?

澄清

我正在寻找一种方法,使用Nuget将代码文件而不是已编译的程序集部署到目标项目。我不想将条件编译符号部署到目标项目(尽管我可以),而是从代码中排除所有条件编译逻辑并处理逻辑以生成与编译器等效的代码文件会做符号。这是代码作为配置,目标项目不需要多个.NET和MVC组合 - 部署符号只会使事情过于复杂。我试图避免为每个单独的MVC / .NET版本组合手动创建和维护代码文件,而是处理条件编译符号以生成与我相同的文件集。

答案

我从http://mcpp.sourceforge.net/download.html下载了C ++预处理器并使用了命令:

mcpp -C -P -DMVC2 -DNET35 Input.cs Output.cs

请注意,我没有使用=作为文档建议。

唯一真正的限制是,如果代码中有#region语句,命令就会崩溃。我能够通过省略它来解决这个问题。它还使代码格式化了一点,但仍保持可编译状态。

2 个答案:

答案 0 :(得分:2)

您可能很幸运使用GNU C预处理器作为this answer提及。

答案 1 :(得分:0)

一种选择是将所有依赖于版本的代码移动到具有公共接口的单独类中。然后使用条件编译一次 - 创建所需类的实例。

这样,您可以编写类似versionAdapter.RegisterProvider()而不是

的内容
this.For<System.Web.Mvc.IFilterProvider>()
                .Singleton()
                .Use<FilterProvider>()