在编译时检测C#版本

时间:2016-10-11 09:20:16

标签: c#

是否可以使用预处理程序指令检测当前版本的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中,但是那些不使用该版本的人也可以编译它。

5 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:2)

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

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

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

    将配置文件的选择委派给构建代理程序,或作为编译项目的使用说明书的一部分。

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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

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

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

您可以在构建脚本中检测到可用的编译器版本后在外部定义符号,但它不值得麻烦的IMO,因为较低版本的C#代码比分散的重复块更易读和可维护围绕你的代码。

答案 4 :(得分:-1)

不确定这样的常数,但......

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

此外: 您可以创建常量:

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

我没有测试过这个。

相关问题