如何设置条件编译变量?

2024-02-01

在 C/C++ 中,您可以在代码中定义宏,如下所示:

#define OLD_WAY  1

尽管我从未这样做过,但我认为 C# 中也可以实现同样的功能。更重要的是,在 C/C++ 中,可以通过执行以下操作来执行一些条件编译逻辑:

#if OLD_WAY == 1
 int i = 0;
#else
 int i = 1;
#endif

好吧,这一切都很酷。我再次假设这样的逻辑在 C# 中是可能的。我想知道的是,如何在项目级别定义常量,以便我可以放入逻辑,如果我以一种方式定义常量或另一代码块,则允许我有条件编译一个代码块如果我不这样定义呢?我假设它是在项目属性中的某个地方完成的,但是我如何以及在哪里定义它?


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“输出详细程度”设置为“详细”,然后进行重建。

构建完成后,检查构建日志的顶部视觉工作室 输出窗口,您将看到可用属性名称及其初始值的列表。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设置条件编译变量? 的相关文章

随机推荐

  • 库模块中的崩溃报告

    我已经尝试过 crashlytics 但不支持 这是我从他们团队得到的回复 感谢您对此的关注 Crashlytics 或 Fabric 的任何部分都不能包含在分发给外部应用程序的任何 SDK 中 正如您提到的 这将导致 SDK 和应用程序发
  • 查看运行“sbt”中“.sbtopts”中的选项

    根据这有帮助post https stackoverflow com a 14561346 409976 我删除了我的 sbtconfig 并添加了 sbtopts cd myProject cat sbtopts J Xmx4G J XX
  • 如何将 UIImage 转换为 BMP 并另存为数据(不是 JPG 或 PNG)

    我正在我的 iOS 应用程序 Swift 3 和仅支持 BMP 格式的应用程序 在 MS Windows 上 之间同步 BMP 图像 在 MS Windows 应用程序上创建的 BMP 图像作为 base64 字符串下载 另存为Data并使
  • 当源中存在其他静态文件时,为什么我无法在 django 项目中添加静态文件?

    我正在尝试为 Heroku 构建一个 Django 应用程序 并且已经完成了民意调查教程并且Heroku 文档 https devcenter heroku com articles django assets 当使用基本的 Django
  • Weld/CDI 的最佳调试技巧是什么?

    Java EE 6 的优点之一是新的依赖项注入框架 具有 Weld 参考实现的 CDI 它促使我们开始以与实现无关的方式内部迁移到 JSR 330 其明确目标是能够拥有核心 jar 被冻结 然后能够添加额外的 jar 提供新的模块来替换核心
  • 删除未使用的 HTTP 处理程序以提高性能和安全性

    在哪里可以获得所有默认 IIS HTTP 处理程序的功能列表 我需要文档 我读过一些博客 出于性能和安全原因 建议删除数十个未使用的 HTTP 处理程序 例如 建议删除 TraceHandler Integrated 和 TraceHand
  • 取消使用 Hangfire.io 计划的正在运行的作业

    我使用hangfire io 库安排作业 我可以观察它在内置仪表板中的处理情况 但是 我的系统要求可以从仪表板取消该作业 有一个选项可以删除正在运行的作业 但这只会更改数据库中作业的状态 并不会停止正在运行的作业 我在文档中看到有可以通过的
  • 如何从经验分布函数中制作样本

    我正在尝试在 Python 上实现非参数引导 它需要获取一个样本 从中构建一个经验分布函数 然后从该 edf 生成一堆样本 我该怎么做 在 scipy 中 如果您知道描述它的确切公式 我只能找到如何创建自己的分布函数 但我只有一个 edf
  • 解释为什么 Array.sort 这样做

    当我们尝试对数字数组进行排序时 人们说使用这个 var numbers 4 2 5 1 3 numbers sort function a b debugger return a gt b 1 1 debugger print number
  • 在SAS中使用循环重命名索引列?

    我有一个数据集 其中变量为 col1 col2 col3 col15 我想将它们重命名为new1 new2 new3 new 15 我可以写15次类似的rename col1 new1 在 SAS 中 但如何使用循环实现此目的 谢谢 首先
  • pip install MySQL-python 返回无法找到 vcvarsall.bat

    我一直在努力pip install MySQL python在 Windows 7 上但它返回unable to find vcvarsall bat 我正在使用Python 3 4 我怎样才能以简单的方式完成这项工作 而无需经历安装 Vi
  • Android 如何查看版本

    我在 2 2 环境中完成了我的应用程序 当我在旧版本中安装我的 apk 时 我收到解析器错误 是否有可能显示我们自己的消息而不是解析器错误消息 据我看来 事实并非如此 做这样的事情 private int GetVersion int ve
  • 如何获取 std::thread() 的 Linux 线程 ID

    我正在玩std thread我想知道如何获得新的线程IDstd thread 我不是在谈论std thread id而是给予线程的操作系统 ID 您可以使用pstree 这仅供我所知 并且仅针对 Linux 平台 不需要可移植 我可以像这样
  • 阻止 jQuery 重复,示例已附

    我必须将 jQuery 附加到发票上 有时我必须批量打印多张发票 当这种情况发生时 我的每张发票都会出现完全相同的 jQuery 并且每次创建我不需要的额外元素时它都会运行 有没有办法让出现多次的 jQuery 仅在它最后一次出现在代码中时
  • 使用 SQL 查询查找最接近的匹配字符串及其子字符串

    我想编写一个查询 它将按顺序获取给定字符串及其子字符串的最接近的匹配字符串 例如 假设我有一列中包含所有名称的表 如果我想搜索名字 ATUL 那么结果应该首先列出所有匹配的不同名称 ATUL then ATU then AT 进而 A 最后
  • href 中的内联 JavaScript

    你怎么能做这样的事情 a href myLink a 并在单击链接时执行 href 中的 js 直接把JS代码放进去就可以了 a href fsljk a 不过 您不应该执行内联脚本 您应该不引人注目地附加事件处理程序 a href bla
  • 同时检测父视图和子视图的 Android-Touch 事件

    目前以下是我的应用程序的布局 LinearLayout Button ScrollView RelativeLayout EditText 我在所有这些之上创建了一个透明的 LinearLayout 实现了 OnTouchListener
  • Knockout 将键值对象绑定到下拉菜单

    我有以下型号 var allCategories id 1 name Red id 5 name Blue function model self this self name ko observable self categoryId k
  • 如何从 Google Play 开发者控制台删除草稿?

    我在 Google Play 开发者控制台上有一个测试草案 它是空的 没有 apk 文件 也没有描述 我只是创建它来检查一些东西 现在草稿就在这里 我找不到删除它的按钮 我怎样才能删除该草稿 我找不到任何有关它的文档 Thanks 1 if
  • 如何设置条件编译变量?

    在 C C 中 您可以在代码中定义宏 如下所示 define OLD WAY 1 尽管我从未这样做过 但我认为 C 中也可以实现同样的功能 更重要的是 在 C C 中 可以通过执行以下操作来执行一些条件编译逻辑 if OLD WAY 1 i