在C/C++中,您可以在代码中定义宏,如下所示:
#define OLD_WAY 1
Run Code Online (Sandbox Code Playgroud)
虽然我从来没有这样做过,但我认为C#中可以使用同样的东西.更重要的是,在C/C++中,可以通过执行以下操作来执行某些条件编译逻辑:
#if OLD_WAY == 1
int i = 0;
#else
int i = 1;
#endif
Run Code Online (Sandbox Code Playgroud)
好的,所以这一切都很酷.而且,我认为这种逻辑在C#中是可能的.我想知道的是,我如何在项目级别定义常量,以便我可以输入逻辑,如果我定义常量的一个方法或另一个代码块,我将允许我条件编译一个代码块如果我不这样定义?我假设它已经在项目的属性中的某个地方完成,但我如何定义它?
Gle*_*den 58
C#编译器csc.exe和C#语言本身不会公开任何预定义的条件编译常量.Visual Studio仅添加DEBUG和TRACE值,可以通过IDE进行配置.IDE还允许您添加自己的任意符号,但由于这些符号基本上是固定的(不变)值,因此该功能的用途有限.
可以通过手动编辑.csproj项目文件来设置更强大的自定义选项.您可以在此处设置条件,以根据MSBuild中可用的大量环境和配置信息有选择地将条件编译符号传播到C#中(请参阅此处和此处,但原则上,可能没有完整列表,因为不同的组件任意提供元数据ad-hoc).
让我们考虑一个有效的例子.有条件编译有用的一种情况是,如果要编写适应构建期间发现的任何工具的代码.通过这种方式,您可以利用最新的语言功能,同时仍然保留在具有旧工具的机器上进行编译的能力,这可能会像预期的那样拒绝外来语法和/或关键字.对于特定的情况下,C#7.0中的Visual Studio 2017年我们可以通过修改.csproj如下:
.csproj文件(摘录):
您还可以识别每个较旧的C#编译器,并在此过程中优雅地降级.检测.NET Framework版本(在StackOverflow [1] [2] [3] [4]上经常请求)和任何其他环境构建条件也是如此.这些留给读者练习,但如果你想从上面复制/粘贴突出显示的行,这里是文本版本.作为屏幕截图的更新,我在这里为条件表达式添加了单引号(即使一切看起来没有它们)
<DefineConstants Condition="'$(VisualStudioVersion)'=='15'">CSHARP7</DefineConstants>
<!-- ... -->
<DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
<!-- ... -->
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
Run Code Online (Sandbox Code Playgroud)
无论如何,通过这种方式,您现在可以使用编写条件C#代码#if… #elif… #else… #endif.继续示例案例,下面的代码使用新的元组语法 - 仅在C#7中可用 - 来交换数组元素.顺便提一下,元组版本不仅更简洁和/或更优雅; 它还可以生成出色的IL代码:
#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
Run Code Online (Sandbox Code Playgroud)
请注意,.csprojIDE 会.csproj在各方面正确处理您的手动自定义.由于IntelliSense我之前展示的IDE代码编辑器可以正确识别和评估条件编译而言的refactoring,$(VisualStudioVersion)"调出"的代码不激活块等.
我还提到.vcxproj有一大堆信息,其中C/C++只有一个例子.不幸的是,很难找出哪些值可用以及它们在构建时可能具有的值.一个技巧是暂时将%项目放入您的.csproj解决方案(如果您还没有)与C#项目一起.如果你右击该项目性质为这个csc.exe,再看看(例如)"附加包含目录"上的DEBUG页面,一个下拉菜单会出现在最右边,当您单击编辑:
您将看到一个带有"宏"按钮的对话框,您可以单击该按钮以TRACE根据IDE中当前选择的平台和配置获取所有可用变量及其预期值的列表.不要忽略列表底部的众所周知的项目元数据字段(前缀为.csproj).
您可以从此屏幕截图中滚动条拇指的大小了解此处有多少内容.(它们按字母顺序列出,我只是滚动到"P"部分的这一部分,因为它具有最少的个人信息).然而,重要的是要注意,(可用的)变量及其值在构建过程中随着时间的推移而发展,因此您可能会在此列表中找到在处理时无法使用.csproj 的项目.
[edit:]在构建过程中和整个构建过程中找出可用属性值的另一种方法是将MSBuild"输出详细程度"设置为"详细",然后重建.
构建完成后,在Visual Studio 输出窗口中检查构建日志的顶部,您将看到可用属性名称及其初始值的列表.
Bri*_*ndy 41
在C#中你可以做#define但你不能像在C++中那样使用它们.
每个定义可以有2种状态:已定义或未定义
在Build下的项目属性中,您可以设置应定义的定义.
您在此处指定的任何内容都将在所有项目文件中定义.
例如,我可以在此字段中定义2个条件编译符号:
#define
然后在我的代码中我可以做这样的事情:
MY_DEFINE1, MY_DEFINE2
Run Code Online (Sandbox Code Playgroud)
或者,您可以对每个文件执行定义,但与C++不同,它们必须位于文件的顶部.
在文件的顶部,您可以使用:
#if MY_DEFINE1
// Do something conditionally
#endif
#if MY_DEFINE2
// Do something else conditionally
#endif
Run Code Online (Sandbox Code Playgroud)
或者您可以在文件的顶部使用:
#define MY_DEFINE2
Run Code Online (Sandbox Code Playgroud)
如果您设置条件编译符号,并且除了可能的文件之外的所有文件中都需要它,那么最后一个.
Mat*_*ira 39
打开项目属性并查看"构建"页面.有一个名为Conditional compilation symbols的框.
| 归档时间: |
|
| 查看次数: |
58253 次 |
| 最近记录: |