Предупреждение CA1416: совместимость платформы
Начиная с .NET 5 правило анализатора кода .NET CA1416 включено по умолчанию. Оно создает предупреждение сборки для вызовов API для конкретных платформ из мест вызовов, которые не проверяют операционную систему.
Описание изменения
Начиная с .NET 5 пакет SDK для .NET включает анализаторы исходного кода .NET. Некоторые из этих правил включены по умолчанию, в том числе CA1416. Если проект содержит код, нарушающий это правило и настроенный на обработку предупреждений как ошибок, это изменение может нарушить сборку. Правило CA1416 информирует вас об использовании API для конкретных платформ из мест, где контекст платформы не проверяется.
Правило CA1416 (анализатор совместимости платформ) хорошо сочетается с другими возможностями, которые появились в .NET 5. В .NET 5 появились атрибуты SupportedOSPlatformAttribute и UnsupportedOSPlatformAttribute, позволяющие указывать платформы, на которых API поддерживается или не поддерживается. В отсутствие этих атрибутов предполагается, что API поддерживается на всех платформах. Эти атрибуты применялись в API для конкретных платформ в основных библиотеках .NET.
В проектах, предназначенных для платформ, для которых используются недоступные API, правило CA1416 помечает любой вызов API, зависящий от платформы, где контекст платформы не проверяется. Большинство API, которые теперь снабжены атрибутами SupportedOSPlatformAttribute и UnsupportedOSPlatformAttribute, вызывают исключения PlatformNotSupportedException, когда они вызываются в неподдерживаемой операционной системе. Теперь, когда эти API отмечены как зависящие от платформы, правило CA1416 помогает предотвратить возникновение исключений PlatformNotSupportedException во время выполнения, добавляя проверки ОС к местам вызовов.
Примеры
Метод Console.Beep(Int32, Int32) поддерживается только в Windows и декорируется
[SupportedOSPlatform("windows")]
. Следующий код выдаст предупреждение CA1416 во время сборки, если проект предназначен дляnet5.0
(кросс-платформенный подход). Но этот код не будет выдавать предупреждение, если проект предназначен для Windows (net5.0-windows
), аGenerateAssemblyInfo
включено для проекта. Действия, которые можно предпринять, чтобы избежать предупреждения, см. в разделе Рекомендуемое действие.public void PlayCMajor() { Console.Beep(261, 1000); }
Метод Image.FromFile(String) не поддерживается в браузере и декорируется
[UnsupportedOSPlatform("browser")]
. Следующий код выдаст предупреждение CA1416 во время сборки, если проект поддерживает платформу браузера.public void CreateImage() { Image newImage = Image.FromFile("SampImag.jpg"); }
Совет
Проекты Blazor WebAssembly и проекты библиотеки классов Razor включают поддержку браузера автоматически. Чтобы вручную добавить браузер в качестве поддерживаемой платформы для проекта, добавьте следующую запись в файл проекта:
<ItemGroup> <SupportedPlatform Include="browser" /> </ItemGroup>
Представленные версии
5,0
Рекомендуемое действие
Убедитесь, что API, относящиеся к конкретной платформе, вызываются только при выполнении кода на соответствующей платформе. Вы можете проверить текущую операционную систему с помощью одного из методов Is<Platform>
в классе System.OperatingSystem. Например OperatingSystem.IsWindows(), перед вызовом API для конкретной платформы.
Можно использовать один из методов Is<Platform>
в условии инструкции if
:
public void PlayCMajor()
{
if (OperatingSystem.IsWindows())
{
Console.Beep(261, 1000);
}
}
Или, если вы не хотите использовать дополнительную инструкцию if
во время выполнения, вызовите Debug.Assert(Boolean).
public void PlayCMajor()
{
Debug.Assert(OperatingSystem.IsWindows());
Console.Beep(261, 1000);
}
Если вы создаете библиотеку, вы можете пометить API как зависящий от платформы. В этом случае проверку требований будут выполнять вызывающие объекты. Можно отметить определенные методы или типы или всю сборку.
[SupportedOSPlatform("windows")]
public void PlayCMajor()
{
Console.Beep(261, 1000);
}
Если вы не хотите исправлять все места вызовов, можно выбрать один из следующих вариантов, чтобы отключить предупреждение.
Чтобы отключить правило CA1416, это можно сделать с помощью
#pragma
флага компилятора NoWarn или при задании серьезностиnone
правила в файле editorconfig.public void PlayCMajor() { #pragma warning disable CA1416 Console.Beep(261, 1000); #pragma warning restore CA1416 }
Чтобы полностью отключить анализ кода, задайте для параметра
EnableNETAnalyzers
значениеfalse
в файле проекта. Дополнительные сведения см. в разделе EnableNETAnalyzers.
Затронутые API
Для платформы Windows:
- все API, указанные в https://github.com/dotnet/designs/blob/main/accepted/2020/windows-specific-apis/windows-specific-apis.md.
- System.Security.Cryptography.DSAOpenSsl
- System.Security.Cryptography.ECDiffieHellmanOpenSsl
- System.Security.Cryptography.ECDsaOpenSsl
- System.Security.Cryptography.RSAOpenSsl
Для платформы Blazor WebAssembly:
- все API, указанные в https://github.com/dotnet/runtime/issues/41087.