C# 编译器csc.exe
并且 C# 语言本身不公开任何预定义常量条件编译 https://learn.microsoft.com/en-us/dotnet/articles/csharp/language-reference/preprocessor-directives/. 视觉工作室只添加了DEBUG
and TRACE
值,可以通过 IDE 配置。 IDE 还允许您添加自己的任意符号,但由于这些符号本质上是固定(不变)值,因此该功能的用途有限。
可以通过手动编辑您的设置来设置更强大的自定义选项.csproj
项目文件。您可以设置状况 https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditions到这里有选择地传播 https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditional-constructs基于大量可用的环境和配置信息将条件编译符号转换为 C#MSBuild https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild (see here https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties and here https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties,但原则上,不可能有完整的列表,因为不同的组件任意贡献元数据ad-hoc).
让我们考虑一个工作示例。条件编译很有用的一种情况是,如果您想要编写适应构建过程中发现的任何工具的代码。通过这种方式,您可以利用最新的语言功能,同时仍然保留使用旧工具在机器上进行编译的能力,这些工具将如预期的那样拒绝外来语法和/或关键字。对于具体情况C# 7.0 https://learn.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7 in 视觉工作室 2017我们可以修改.csproj
如下:
.csproj 文件(摘录):
您还可以识别每个较旧的 C# 编译器,并在此过程中优雅地降级。检测时也是如此.NET框架版本(Stack Overflow 上经常请求的[1] https://stackoverflow.com/questions/1449925/is-it-possible-to-conditionally-compile-to-net-framework-version
[2] https://stackoverflow.com/questions/2923210/conditional-compilation-and-framework-targets
[3] https://stackoverflow.com/questions/3436526/detect-target-framework-version-at-compile-time
[4] https://stackoverflow.com/questions/4890095/conditional-compilation-for-net-4)和任何其他环境构建条件。这些留给读者作为练习,但如果您想复制/粘贴上面突出显示的行,这里是文本版本。作为屏幕截图的更新,我在此处的条件表达式中添加了单引号(即使没有它们一切似乎都可以工作)
<DefineConstants Condition="'$(VisualStudioVersion)'=='15'">CSHARP7</DefineConstants>
<!-- ... -->
<DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
<!-- ... -->
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
无论如何,现在你可以用这种方式写条件 C# 代码 using #if… #elif… #else… #endif
。继续示例案例,下面的代码使用新的元组语法(仅在 C# 7 中可用)来交换数组元素。顺便说一句,元组版本不仅更加简洁和/或优雅,而且更加简洁。它还生成优秀的 CIL 代码:
#if CSHARP7
(rg[i], rg[j]) = (rg[j], rg[i]); // Swap elements: tuple syntax
#else
var t = rg[i]; // Swap elements: clunky
rg[i] = rg[j];
rg[j] = t;
#endif
请注意,视觉工作室 http://en.wikipedia.org/wiki/Microsoft_Visual_Studio IDE does正确处理您的手册.csproj
各个方面的定制。鉴于.csproj
我之前展示过,IDE 代码编辑器可以正确识别和评估条件编译,以便IntelliSense
, refactoring
、“调暗”不活动代码块等。
我还提到过MSBuild http://en.wikipedia.org/wiki/MSBuild拥有大量可用信息,其中$(VisualStudioVersion)
这只是一个例子。不幸的是,要找出哪些值可用以及它们在构建时可能具有哪些值并不容易。一个技巧是暂时放置一个C++项目到你的视觉工作室解决方案(如果您还没有)与您的 C# 项目一起提供。如果您右键单击项目属性为了这.vcxproj
然后查看(例如)“其他包含目录”C/C++
页面,当您点击编辑时,最右侧会出现一个下拉菜单:
您将看到一个带有“宏”按钮的对话框,单击该按钮即可获取所有可用 MSBuild 变量的列表以及根据当前在 IDE 中选择的平台和配置的预期值。不要忽视众所周知的项目元数据 https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-well-known-item-metadata字段(前缀为%
)位于列表底部。
您可以通过此屏幕截图中滚动条拇指的大小了解这里有多少内容。 (它们按字母顺序列出;我只是滚动到“P”部分的这一部分,因为它的个人信息很少。)但是,值得注意的是,(可用)变量及其值在构建过程中,因此您可能会在此列表中找到您无法使用的项目.csproj
在处理时.
找出在构建过程中和整个构建过程中可用的属性值的另一种方法是将 MSBuild“输出详细程度”设置为“详细”,然后进行重建。
构建完成后,检查构建日志的顶部视觉工作室 输出窗口,您将看到可用属性名称及其初始值的列表。