【问题标题】:What is the proper way to handle error CA1416 for .NET core builds?为 .NET 核心构建处理错误 CA1416 的正确方法是什么?
【发布时间】:2021-11-25 07:03:33
【问题描述】:

这是我的 C# 代码 sn-p:

if (Environment.IsWindows) {
   _sessionAddress = GetSessionBusAddressFromSharedMemory();
}
...
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
private static string GetSessionBusAddressFromSharedMemory() {
   ...
}

当我运行构建时,我得到一个错误:

error CA1416: 'GetSessionBusAddressFromSharedMemory()' is supported on 'windows' 

我的逻辑是仅当我在 Windows 上时才调用该方法。在 Ubuntu 上构建时如何关闭此警告?问候。

【问题讨论】:

  • MSDN says ... "推荐操作:使用 System.OperatingSystem 类中的 Is 方法之一检查当前操作系统,例如 OperatingSystem.IsWindows() , 在调用特定于平台的 API 之前。"
  • 这个错误是指运行应用的服务器系统,还是访问应用的用户系统?

标签: c# .net-core


【解决方案1】:

您可以使用预处理器指令来确保该方法仅在编译时在 Windows 中可见:

#if Windows
private static string GetSessionBusAddressFromSharedMemory() 
{
   ...
}
#endif

要定义指令,您需要更新您的 csproj,如下所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
    <IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
    <IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
  </PropertyGroup>
  <PropertyGroup Condition="'$(IsWindows)'=='true'">
    <DefineConstants>Windows</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(IsOSX)'=='true'">
    <DefineConstants>OSX</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(IsLinux)'=='true'">
    <DefineConstants>Linux</DefineConstants>
  </PropertyGroup>
</Project>

【讨论】:

  • 这会在编译时评估操作系统,而问题要求在运行时进行评估。想象一下,例如您在 Windows 上构建,但面向 Linux。
  • 感谢您的帮助。然而,克劳斯是正确的。当操作系统是 Windows 和 Linux 逻辑时,我的代码必须调用 Windows 代码。
  • JensG对该问题提供的评论是正确的方法。
【解决方案2】:

如果您可以控制Environment.IsWindows 属性,则可以将[SupportedOSPlatformGuard("windows")] 属性应用于该属性:

public class Environment
{
    [SupportedOSPlatformGuard("windows")]
    public bool IsWindows => OperatingSystem.IsWindows;
}

然后 CA1416 分析器将识别守卫并且不会在条件内发出警告:

if (Environment.IsWindows) {
   _sessionAddress = GetSessionBusAddressFromSharedMemory(); // no warning
}

对于more info

【讨论】:

    【解决方案3】:

    您可以切换到RuntimeInformation.IsOSPlatform查看。 Next 将只对最后一个子句发出警告:

    public void M()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            Console.WriteLine(GetSessionBusAddressFromSharedMemory());
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            Console.WriteLine(GetSessionBusAddressFromSharedMemoryUnix());
        }
        else
        {
            Console.WriteLine(GetSessionBusAddressFromSharedMemoryUnix()); // warning
        }
    }
    
    [SupportedOSPlatform("windows")]
    private static string GetSessionBusAddressFromSharedMemory()
    {
        return "win";
    }
    
    [SupportedOSPlatform("linux")]
    private static string GetSessionBusAddressFromSharedMemoryUnix()
    {
        return "lin";
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 2017-09-20
      • 2021-12-16
      • 2018-09-21
      相关资源
      最近更新 更多