如何在 #if 语句中设置 .NET Core 以进行编译

本文关键字:Core 编译 NET 设置 #if 语句 | 更新日期: 2023-09-27 17:58:01

我创建了一个多目标框架项目。我使用这样的东西:

  #if NET40
    Console.WriteLine("Hello from .NET Core 4");
  #endif

但是我找不到 .NET Core 的通配符。我试过了:

   #if NETCOREAPP1.0
     Console.WriteLine("Hello from .NET Core");
   #endif

但这不是有效的说法。

如何在 #if 语句中设置 .NET Core 以进行编译

你需要

一个下划线,_,而不是一个点:

NETCOREAPP1_0或最近的NETCOREAPP1_1NETCOREAPP2_0

SDK 样式项目中的目标框架文档包括不同预处理器符号的列表。

.NET 框架

NETFRAMEWORK, NET48, NET472, NET471, NET47, NET462, NET461, NET46, NET452, NET451, NET45, NET40, NET35, NET20

.NET 标准

NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, NETSTANDARD1_1, NETSTANDARD1_0

.NET 5+ 和 .NET Core

NET, NET6_0, NET6_0_ANDROID, NET6_0_IOS, NET6_0_MACOS, NET6_0_MACCATALYST, NET6_0_TVOS, NET6_0_WINDOWS, NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, NETCOREAPP2_0, NETCOREAPP1_1, NETCOREAPP1_0

对于 Mono,

您通常可以使用您的 Mono 版本已知的 NetFramework 绰号。例如,Mono 6.12包括从2.0到4.8的所有NetFramework版本。但是,如果你必须认识到单声道本身,那么MONO__MonoCS__都应该被定义。

Devon 对 Visual Studio 2017 .csproj 文件的答案的扩展:

查看此处的表格,您可以使用正则表达式轻松定义常量。因此,如果添加/更改了目标框架,则无需考虑更新条件。

<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^net'd'))">
  <DefineConstants>NETFRAMEWORK</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^netstandard'd'))">
  <DefineConstants>NETSTANDARD</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^netcoreapp'd'))">
  <DefineConstants>NETCORE</DefineConstants>
</PropertyGroup>

用法:

#if NETFRAMEWORK
    FrameworkSpecific();
#endif
#if NETSTANDARD
    StandardSpecific();
#endif
#if NETCORE
    CoreSpecific();
#endif

您可以通过以下方式定义任何自定义条件编译符号 (project.json(:

"frameworks": {
    "net40": {
      "buildOptions": {
        "define": ["NET_40"]
      }
    },
    "netstandard1.5": {
      "buildOptions": {
        "define": [ "NET_STANDARD" ]
      }
    }
}

这种方法似乎更实用,因为您可以对多个目标使用相同的条件符号,而无需编写类似

#if NET20 && NET 40 && NET45

对于新的 Visual Studio 2017 .csproj 项目系统,可以在使用跨平台工具开发库、如何多目标中找到可用符号的完整列表。

您可以在 .csproj 文件中为其创建复合常量,如下所示:

  <PropertyGroup Condition="'$(TargetFramework)' == 'net451' Or '$(TargetFramework)' == 'net461' ">
    <DefineConstants>FULLFRAMEWORK;FULL</DefineConstants>
  </PropertyGroup>

然后,您可以在#if编译器指令中使用它,如下所示:

#if FULLFRAMEWORK
        private bool DoSomethingFullFrameworkSpecific()
        {
            var connectionStringSetting = ConfigurationManager.ConnectionStrings[connectionStringName];
            return connectionStringSetting != null;
        }
#endif

虽然Vitaliy Fedorchenko的回答是正确的,但应该注意的是,.NET Core xproj项目类型中存在一个错误。当您通过项目设置定义条件编译符号时,它将元素定义为"定义",但这是不正确的。它应该创建一个名为"定义"的元素。可以通过手动编辑 project.json 文件来解决此问题。

我已经在两个地方记录了这个错误,Microsoft。请花时间向Microsoft登记您的烦恼,以便他们最终解决它,而不是给其他人带来这种悲伤。

此线程对问题进行了详细说明,包括重现步骤和屏幕截图:

NET Core Visual Studio 项目的 3 个问题 #4022

这是Microsoft连接错误报告:

https://connect.microsoft.com/VisualStudio/feedbackdetail/view/2983351/conditional-compilation-symbols-broken-in-net-core-projects#tabs