【问题标题】:Detect the C# version at compile time在编译时检测 C# 版本
【发布时间】:2016-10-11 09:20:16
【问题描述】:

是否可以在编译时通过预处理指令检测当前 C# 版本是否为 6 或更高版本?

我想做这样的事情:

var myVar = ...;
string name;

#if VERSION_6_OR_MORE
    name = nameof(myVar);
#else
    name = "myVar";
#endif

我使用 Visual Studio 2015 和 C# 6,所以我可以使用 nameof()。然而,其他想要编译此代码的人可能正在使用旧版本,其中不存在 nameof()

我想使用预处理器指令,这样我就可以将 nameof() 保留在 C# 6 中,但不使用该版本的其他人也可以编译它。

【问题讨论】:

标签: c#


【解决方案1】:

nameof() 运算符旨在减少维护:使用它您不会在字符串中隐藏标识符,因此当您重命名变量、参数或成员时,使用它的位置(例如 ArgumentNullException(nameof(paramName)) ) 将在您重构 paramName 名称时更新。

现在使用您的方法,您实际上是 加倍 维护表面而不是减少它(因为您现在拥有字符串变体 nameof() 版本,两者都必须维护),完全否定了nameof()的使用。

因此,如果您想支持较旧的 C# 版本,请坚持在这些版本中工作的功能:改用字符串中的标识符。

【讨论】:

  • 你一定是对的,我更喜欢使用nameof,它允许重命名变量而不必检查依赖于这个变量的所有字符串。但是如果我的同事不能更新,它就很难维护。那我就放弃nameof :-(
【解决方案2】:

您可以在项目文件中明确指定语言版本并定义条件常量:

<LangVersion>6</LangVersion>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants Condition="'$(LangVersion)' == '6'">DEBUG;TRACE;LANG_VERSION_6</DefineConstants>

【讨论】:

    【解决方案3】:

    我不知道预先存在的指令。但是,您可以这样做:

    1. 定义两个构建配置:说CSharp6和CSharp5(在配置 经理)。
    2. 从配置管理器中选择C6,然后进入项目属性。并定义一个符号 CSHARP6。
    3. 更改配置并转到 CSharp5
    4. 再次打开项目属性并定义一个新符号:CSHARP5

    然后你的指令条件看起来像:

    #if CSHARP6
        name = nameof(myVar);
    #else
        name = "myVar";
    #endif
    

    将配置文件的选择委托给构建代理,或作为项目编译说明手册的一部分。

    【讨论】:

      【解决方案4】:

      C# 编译器不允许您使用数值定义符号。任何符号要么是 defined 要么是 undefined,这意味着它只是一个布尔值。

      #define//define#if 都不支持布尔值以外的任何语法。

      到目前为止,所有 C# 版本都向后兼容以前的版本(除了一些细微差别,例如 foreach 循环中的迭代器变量语义),所以如果你想编写与旧版本兼容的代码,请不要使用新版本功能。

      您可以在构建脚本中检测到可用的编译器版本后在外部定义一个符号,但这不值得麻烦 IMO,因为较低版本的 C# 代码将比散布在代码周围的重复块更清晰和可维护。

      【讨论】:

        【解决方案5】:

        不确定这样的常量,但是...

        typeof(int).Assembly.ImageRuntimeVersion 之类的东西可以在运行时提供帮助。

        另外: 您可以创建常量:

        <DefineConstants Condition=" '$(LanguageVersion)' == 'v6.0' ">USING_CS6</DefineConstants>
        <DefineConstants Condition=" '$(LanguageVersion)' != 'v6.0' ">NOT_USING_CS6</DefineConstants>
        

        不过我还没有测试过。

        【讨论】:

        • 我不这么认为,op 想在运行时找到这个。
        • @Fka,现在是编译时间。
        • @Fka,Wai 的意思是您在第一条评论中的句子并不代表您认为的意思。事实上,这与您的意图相反。
        猜你喜欢
        • 1970-01-01
        • 2011-04-05
        • 2011-03-27
        • 1970-01-01
        • 1970-01-01
        • 2011-03-19
        • 2014-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多