【问题标题】:Can I define constants based on the runtime identifier in .NET Core?我可以根据 .NET Core 中的运行时标识符定义常量吗?
【发布时间】:2018-05-04 01:52:46
【问题描述】:

我有一个 .NET Core 控制台应用程序。我的目标是能够有条件地DLLImport 一个函数并调用它,但仅限于 Windows 运行时。

我想如果我可以访问 csproj 文件中的运行时标识符,我可以有条件地为该运行时定义一个常量,然后在我的 c# 中我可以包围 DLLImport 并调用 #if/#endif 块.

是否可以根据构建项目的运行时在csproj 中设置编译常量?这专门针对面向 .NET Core 的 SDK 样式的项目格式(以 <Project Sdk="Microsoft.NET.Sdk"> 开头)。

注意:this question 接近,但适用于project.json 风格的项目。

或者,有没有更好的方法来实现我的目标?

【问题讨论】:

  • 您可以根据某些条件在 .csproj 中定义编译器常量。例如: TRACE;DEBUG;ABC;NETCOREAPP2_0 这个xml节点是直接位于根“项目”节点中。

标签: c# .net-core interop runtime-identifier


【解决方案1】:

如果您通过传递不同的 --runtime 选项(MSBuild 属性 RuntimeIdentifier)为不同的运行时构建和发布,您可以在 csproj 文件中以该属性为条件(允许您在 C# 代码中使用 #if BUILT_FOR_WINDOWS) :

<PropertyGroup>
  <DefineConstants Condition="'$(RuntimeIdentifier)' == 'win-x64'">$(DefineConstants);BUILT_FOR_WINDOWS</DefineConstants>
</PropertyGroup>

不过,您也可以在运行时使用以下方法测试当前操作系统:

using System.Runtime.InteropServices;
…

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
    // call windows function here
}
else
{
    // do something else here
}

只要没有在找不到库/方法的操作系统上调用标有[DllImport(…)] 的函数,就不会有任何问题。请注意DllImport() 还可以根据操作系统探测不同的库 - 所以DllImport("foo") 会检查foo.dllfoo.dyliblibfoo.so 等。

【讨论】:

【解决方案2】:

添加到 Martin Ullrich 的答案:如果您想在引用的库项目中定义基于 RuntimeIdentifier 的常量,而不是具有应用程序入口点的项目,请确保包含您在 @ 中使用的标识符列表项目的.csproj文件中的987654323@属性,例如:

<PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <RuntimeIdentifiers>linux-x64;linux-arm</RuntimeIdentifiers>
</PropertyGroup>

如果你不这样做,那么常量将不会被定义为 RuntimeIdentifier 属性将不会像我的情况一样传递给 csproj。

来源:https://github.com/dotnet/core/issues/2678#issuecomment-498967871

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2014-08-24
    • 2020-05-13
    • 2020-12-22
    • 2023-01-19
    相关资源
    最近更新 更多