【问题标题】:How to set .NET Core in #if statement for compilation如何在#if 语句中设置.NET Core 进行编译
【发布时间】:2023-04-03 09:31:02
【问题描述】:

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

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

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

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

但这不是有效的陈述。

【问题讨论】:

  • 更改为#if NETCOREAPP1_0
  • 是的,将. 替换为_
  • Here msdn 列出了预定义的 .net 核心符号。

标签: c# asp.net-core asp.net-core-mvc .net-core asp.net-core-1.0


【解决方案1】:

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

NETCOREAPP1_0 或更新的NETCOREAPP1_1NETCOREAPP2_0

Target frameworks in SDK-style projects 的文档包括不同预处理器符号的列表。

.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 本身,那么MONO__MonoCS__ 都应该被定义。

【讨论】:

【解决方案2】:

Devon's answer 的扩展名用于 Visual Studio 2017 .csproj 文件:

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

<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

【讨论】:

  • 好主意;遗憾的是,这些 NETFRAMEWORK / NETSTANDARD / NETCORE 符号不能作为编译器的标准部分使用
  • 您应该主要编写可以在任何地方运行的代码,而不依赖于编译器标志。这种方法仅适用于您真正需要的极少数情况。
  • @gallivantor Seems like they are now(.NET Core 的符号除外称为NETCOREAPP
  • 我认为这个 ([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^net\d'))) 语句为 .net5.0 提供了错误的结果和.net 6.0
【解决方案3】:

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

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

    }
}

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

#if NET20 && NET 40 && NET45

【讨论】:

  • 您在哪里定义 .net 标准项目?您能否更新您的答案以显示使用多个目标
  • 发布时,它是正确的。但 MS 已从 project.json 文件转移到 .csproj 文件。 docs.microsoft.com/en-us/dotnet/core/migration
【解决方案4】:

对于新的 Visual Studio 2017 .csproj 项目系统,您可以在 Developing Libraries with Cross Platform Tools, How to Multitarget 中找到可用符号的完整列表。

您可以在 .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

【讨论】:

    【解决方案5】:

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

    我已经在两个地方向 Microsoft 记录了这个错误。请花时间向 Microsoft 登记您的烦恼,以便他们最终解决问题,而不是给其他人造成这种痛苦。

    这个帖子有详细的问题解释和重现步骤,还有截图:

    3 Issues with NET Core Visual Studio Projects #4022

    这是 Microsoft Connect 错误报告:

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

    【讨论】:

    • 微软已停止在 Vs2017 中对 xproj 和 project.json 的支持
    • 第二个链接(实际上)已损坏:“Microsoft Connect 已停用”。无论如何,也许是时候更新了? (注意:结果应该到处都是“编辑:”或“更新:”(答案本身的历史记录),但好像答案是今天写的,比如“直到版本这个它有问题X,并且在2018-01-31版本中修复了ExtraGood。在Visual Studio 2017中,它被替换为Y。”
    猜你喜欢
    • 2013-08-20
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 2012-05-03
    相关资源
    最近更新 更多