Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
| Vlastnost | Hodnota |
|---|---|
| ID pravidla | CA1416 |
| Název | Ověřit kompatibilitu platformy |
| Kategorie | Vzájemná funkční spolupráce |
| Oprava způsobující chybu nebo chybu způsobující chybu | Nenarušující |
| Povoleno ve výchozím nastavení v .NET 10 | Jako upozornění |
Příčina
Porušení se hlásí, pokud se rozhraní API specifické pro platformu používá v kontextu jiné platformy nebo pokud není ověřená (platforma neutrální). Porušení se hlásí také v případě, že se používá rozhraní API, které není podporováno pro cílovou platformu projektu.
Toto pravidlo je ve výchozím nastavení povolené jenom pro projekty, které cílí na .NET 5 nebo novější. Můžete ho ale povolit pro projekty, které cílí na jiné architektury.
Popis pravidla
Rozhraní .NET 5 přidalo nové atributy SupportedOSPlatformAttribute a UnsupportedOSPlatformAttributepro přidávání poznámek rozhraní API specifických pro platformu. V rámci názvu platformy je možné vytvořit instanci obou atributů s čísly verzí nebo bez. Lze je také použít vícekrát s různými platformami.
- Neoznačené rozhraní API se považuje za funkční na všech platformách operačního systému (OS).
- Rozhraní API označené
[SupportedOSPlatform("platformName")]jako přenosné pouze na určené platformy operačního systému. Pokud je platforma podmnožinou jiné platformy, atribut znamená, že se tato platforma podporuje také. - Rozhraní API označené
[UnsupportedOSPlatform("platformName")]jako nepodporované na zadaných platformách operačního systému se považuje za nepodporované. Pokud je platforma podmnožinou jiné platformy, atribut znamená, že tato platforma není podporována.
V jednom rozhraní API můžete kombinovat a [SupportedOSPlatform] atributy[UnsupportedOSPlatform]. V tomto případě platí následující pravidla:
-
Seznam povolených položek Pokud je nejnižší verze pro každou platformu
[SupportedOSPlatform]operačního systému atributem, rozhraní API se považuje za podporované pouze uvedenými platformami a nepodporované všemi ostatními platformami. Seznam může mít atribut se stejnou[UnsupportedOSPlatform]platformou, ale pouze s vyšší verzí, která označuje, že rozhraní API je z této verze odebráno. -
Odepřít seznam. Pokud je nejnižší verze pro každou platformu
[UnsupportedOSPlatform]operačního systému atributem, rozhraní API se považuje za nepodporované pouze pro uvedené platformy a podporované všemi ostatními platformami. Seznam může mít atribut se stejnou[SupportedOSPlatform]platformou, ale pouze s vyšší verzí, která označuje, že rozhraní API je od této verze podporované. -
Nekonzistentní seznam Pokud je
[SupportedOSPlatform]nejnižší verze některých platforem, ale[UnsupportedOSPlatform]pro jiné platformy, považuje se tato kombinace za nekonzistentní. Některé poznámky v rozhraní API se ignorují. V budoucnu můžeme zavést analyzátor, který v případě nekonzistence vytvoří upozornění.
Pokud přistupujete k rozhraní API s poznámkami s těmito atributy z kontextu jiné platformy, můžete zobrazit porušení CA1416.
Cílové platformy TFM
Analyzátor nekontroluje cílové platformy monikeru (TFM) cílové platformy z vlastností NÁSTROJE MSBuild, například <TargetFramework> nebo <TargetFrameworks>. Pokud má TFM cílovou platformu, sada .NET SDK vloží SupportedOSPlatform do souboru AssemblyInfo.cs atribut s názvem cílové platformy, který analyzátor využívá. Pokud je net5.0-windows10.0.19041například TFM , sada SDK vloží [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")] atribut do souboru AssemblyInfo.cs a celé sestavení se považuje pouze za Windows. Proto volání rozhraní API jen pro Windows ve verzi 7.0 nebo novější nezpůsobí žádná upozornění v projektu.
Poznámka:
Pokud je generování souboru AssemblyInfo.cs pro projekt zakázané (to znamená, že <GenerateAssemblyInfo> vlastnost je nastavena na false), nelze přidat požadovaný atribut úrovně SupportedOSPlatform sestavení sadou SDK. V takovém případě se zobrazí upozornění na využití rozhraní API specifická pro konkrétní platformu, i když na tuto platformu cílíte. Pokud chcete upozornění vyřešit, povolte generování AssemblyInfo.cs souboru nebo přidejte atribut do projektu ručně.
Porušení
Pokud přistupujete k rozhraní API, které je podporované jenom na zadané platformě (
[SupportedOSPlatform("platformName")]) z kódu dostupného na jiných platformách, uvidíte následující porušení: "API" je podporováno na platformě PlatformName.// An API supported only on Linux. [SupportedOSPlatform("linux")] public void LinuxOnlyApi() { } // API is supported on Windows, iOS from version 14.0, and MacCatalyst from version 14.0. [SupportedOSPlatform("windows")] [SupportedOSPlatform("ios14.0")] // MacCatalyst is a superset of iOS, therefore it's also supported. public void SupportedOnWindowsIos14AndMacCatalyst14() { } public void Caller() { LinuxOnlyApi(); // This call site is reachable on all platforms. 'LinuxOnlyApi()' is only supported on: 'linux' SupportedOnWindowsIos14AndMacCatalyst14(); // This call site is reachable on all platforms. 'SupportedOnWindowsIos14AndMacCatalyst14()' // is only supported on: 'windows', 'ios' 14.0 and later, 'MacCatalyst' 14.0 and later. }Poznámka:
K porušení dojde pouze v případě, že projekt nebude cílit na podporovanou platformu (
net5.0-differentPlatform). To platí také pro projekty s více cíli. K žádnému porušení nedojde, pokud projekt cílí na zadanou platformu (net5.0-platformName) aAssemblyInfo.cs generování souborů je pro projekt povolené.Přístup k rozhraní API, které je přiřazeno
[UnsupportedOSPlatform("platformName")]z kontextu, který cílí na nepodporovanou platformu, může způsobit porušení: "API" není podporováno na platformě PlatformName.// An API not supported on Android but supported on all other platforms. [UnsupportedOSPlatform("android")] public void DoesNotWorkOnAndroid() { } // An API was unsupported on Windows until version 10.0.18362. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.18362")] public void StartedWindowsSupportFromCertainVersion() { } public void Caller() { DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android' StartedWindowsSupportFromCertainVersion(); // This call site is reachable on all platforms. 'StartedWindowsSupportFromCertainVersion()' is unsupported on: 'windows' 10.0.18362 and before }
Poznámka:
Pokud vytváříte aplikaci, která necílí na nepodporovanou platformu, nebudete dostávat žádná porušení. K porušení dojde pouze v následujících případech:
Projekt cílí na platformu, která je přiřazená jako nepodporovaná.
Je
platformNamesoučástí výchozí skupiny položek NÁSTROJE MSBuild<SupportedPlatform>.platformNameje ručně zahrnutý do skupiny položek nástroje MSBuild<SupportedPlatform>.<ItemGroup> <SupportedPlatform Include="platformName" /> </ItemGroup>
Jak opravit porušení
Doporučeným způsobem řešení porušení je zajistit, abyste při spouštění na příslušné platformě volali pouze rozhraní API specifická pro danou platformu. Toho můžete dosáhnout vyloučením kódu během sestavení pomocí #if a multi-targetingu nebo podmíněným voláním kódu během běhu. Analyzátor rozpozná ochranu platformy ve OperatingSystem třídě a System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform.
Potlačte porušení tím, že obklopíte web volání standardními metodami ochrany platformy nebo vlastními rozhraními API ochrany ochrany anotací s SupportedOSPlatformGuardAttribute nebo UnsupportedOSPlatformGuardAttribute.
// An API supported only on Linux. [SupportedOSPlatform("linux")] public void LinuxOnlyApi() { } // API is supported on Windows, iOS from version 14.0, and MacCatalyst from version 14.0. [SupportedOSPlatform("windows")] [SupportedOSPlatform("ios14.0")] // MacCatalyst is a superset of iOS, therefore it's also supported. public void SupportedOnWindowsIos14AndMacCatalyst14() { } public void Caller() { LinuxOnlyApi(); // This call site is reachable on all platforms. 'LinuxOnlyApi()' is only supported on: 'linux'. SupportedOnWindowsIos14AndMacCatalyst14(); // This call site is reachable on all platforms. 'SupportedOnWindowsIos14AndMacCatalyst14()' // is only supported on: 'windows', 'ios' 14.0 and later, 'MacCatalyst' 14.0 and later. } [SupportedOSPlatformGuard("windows")] // The platform guard attributes used [SupportedOSPlatformGuard("ios14.0")] private readonly bool _isWindowOrIOS14 = OperatingSystem.IsWindows() || OperatingSystem.IsIOSVersionAtLeast(14); // The warnings are avoided using platform guard methods. public void Caller() { if (OperatingSystem.IsLinux()) // standard guard examples { LinuxOnlyApi(); // no diagnostic } if (OperatingSystem.IsIOSVersionAtLeast(14)) { SupportedOnWindowsAndIos14(); // no diagnostic } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { SupportedOnWindowsAndIos14(); // no diagnostic } if (_isWindowOrMacOS14) // custom guard example { SupportedOnWindowsAndIos14(); // no diagnostic } } // An API not supported on Android but supported on all other platforms. [UnsupportedOSPlatform("android")] public void DoesNotWorkOnAndroid() { } // An API was unsupported on Windows until version 10.0.18362. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.18362")] public void StartedWindowsSupportFromCertainVersion(); public void Caller() { DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android' StartedWindowsSupportFromCertainVersion(); // This call site is reachable on all platforms. 'StartedWindowsSupportFromCertainVersion()' is unsupported on: 'windows' 10.0.18362 and before. } [UnsupportedOSPlatformGuard("android")] // The platform guard attribute bool IsNotAndroid => !OperatingSystem.IsAndroid(); public void Caller() { if (!OperatingSystem.IsAndroid()) // using standard guard methods { DoesNotWorkOnAndroid(); // no diagnostic } // Use the && and || logical operators to guard combined attributes. if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(10, 0, 18362)) { StartedWindowsSupportFromCertainVersion(); // no diagnostic } if (IsNotAndroid) // custom guard example { DoesNotWorkOnAndroid(); // no diagnostic } }Analyzátor také System.Diagnostics.Debug.Assert respektuje jako prostředek, který brání dosažení kódu na nepodporovaných platformách. Použití
Debug.Assertumožňuje, aby se kontrola v případě potřeby ořízla z buildů vydaných verzí.// An API supported only on Linux. [SupportedOSPlatform("linux")] public void LinuxOnlyApi() { } public void Caller() { Debug.Assert(OperatingSystem.IsLinux()); LinuxOnlyApi(); // No diagnostic }Můžete se rozhodnout, že vlastní rozhraní API označíte jako specifická pro konkrétní platformu a efektivně předáte požadavky volajícím. Atributy platformy můžete použít na libovolná z následujících rozhraní API:
- Typy
- Členové (metody, pole, vlastnosti a události)
- Sestavení
[SupportedOSPlatform("windows")] [SupportedOSPlatform("ios14.0")] public void SupportedOnWindowsAndIos14() { } [SupportedOSPlatform("ios15.0")] // call site version should be equal to or higher than the API version public void Caller() { SupportedOnWindowsAndIos14(); // No diagnostics } [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.18362")] public void StartedWindowsSupportFromCertainVersion(); [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.18362")] public void Caller() { StartedWindowsSupportFromCertainVersion(); // No diagnostics }Při použití atributu na úrovni sestavení nebo typu se považují všechny členy v rámci sestavení nebo typu za specifické pro platformu.
[assembly:SupportedOSPlatform("windows")] public namespace ns { public class Sample { public void SupportedOnWindows() { } public void Caller() { SupportedOnWindows(); // No diagnostic as call site and calling method both windows only } } }
Kdy potlačit upozornění
Odkazování na rozhraní API specifická pro platformu bez správného kontextu platformy nebo ochrany se nedoporučuje. Tuto diagnostiku však můžete potlačit příznakem #pragma kompilátoru NoWarn nebo nastavením závažnosti pravidla na none soubor .editorconfig .
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }
public void Caller()
{
#pragma warning disable CA1416
LinuxOnlyApi();
#pragma warning restore CA1416
}
Konfigurace kódu pro analýzu
Analyzátor je ve výchozím nastavení povolený jenom pro projekty, které cílí na .NET 5 nebo novější a mají hodnotu AnalysisLevel 5 nebo vyšší. Můžete ji povolit pro cílové architektury nižší než net5.0 přidáním následujícího páru klíč-hodnota do souboru .editorconfig v projektu:
dotnet_code_quality.enable_platform_analyzer_on_pre_net5_target = true
Viz také
- CA1422: Ověření kompatibility platformy
- Analyzátor kompatibility platformy (koncepční)
- Přidávání poznámek k rozhraním API pro konkrétní platformu a zjišťování jejího použití
- Přidávání poznámek k rozhraním API jako nepodporovaných na konkrétních platformách
- Názvy cílových rozhraní v .NET 5
- Pravidla interoperability