是否可以使用预处理程序指令检测当前版本的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中,但是那些不使用该版本的人也可以编译它。
答案 0 :(得分:5)
nameof()
运算符旨在减少维护:使用它时,您没有隐藏在字符串中的标识符,因此当您重命名变量,参数或成员时,您使用它的位置(例如{重构ArgumentNullException(nameof(paramName))
名称时会更新{1}}。
现在使用您的方法,您实际上加倍您的维护表面而不是减少它(因为您现在拥有字符串变体和 paramName
版本,两者都必须维护),否定完全使用nameof()
。
因此,如果您想支持较旧的C#版本,请坚持使用适用于这些版本的功能:在字符串中使用标识符。
答案 1 :(得分:2)
我不知道预先存在的指令。但是,这是你可以做的:
然后您的指令条件如下:
#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>
我没有测试过这个。