CA1416: Platformkompatibilitás ellenőrzése
Tulajdonság | Érték |
---|---|
Szabályazonosító | CA1416 |
Cím | Platformkompatibilitás ellenőrzése |
Kategória | Együttműködési lehetőség |
A javítás kompatibilitástörő vagy nem törik | Nem törés |
Alapértelmezés szerint engedélyezve a .NET 8-ban | Figyelmeztetésként |
Ok
A szabálysértések akkor jelennek meg, ha egy platformspecifikus API-t használnak egy másik platform kontextusában, vagy ha a platform nincs ellenőrizve (platformsemleges). A szabálysértések akkor is jelentkeznek, ha a projekt célplatformján nem támogatott API-t használnak.
Ez a szabály alapértelmezés szerint csak a .NET 5 vagy újabb verziót megcélzott projektek esetében engedélyezett. Más keretrendszereket célzó projektek esetében azonban engedélyezheti.
Szabály leírása
A .NET 5 új attribútumokat adott hozzá, SupportedOSPlatformAttribute és UnsupportedOSPlatformAttributea platformspecifikus API-k megjegyzéseihez. Mindkét attribútum példányosítható verziószámmal vagy anélkül a platformnév részeként. A különböző platformokon többször is alkalmazhatók.
- A nem módosított API-k minden operációsrendszer-platformon működnek.
- A megjelölt
[SupportedOSPlatform("platformName")]
API-k csak a megadott operációsrendszer-platformokon hordozhatónak minősülnek. Ha a platform egy másik platform részhalmaza, az attribútum azt jelenti, hogy a platform is támogatott. - A megjelölt
[UnsupportedOSPlatform("platformName")]
API-k a megadott operációsrendszer-platformokon nem támogatottnak minősülnek. Ha a platform egy másik platform részhalmaza, az attribútum azt jelenti, hogy a platform szintén nem támogatott.
Egyetlen API-n kombinálhat [SupportedOSPlatform]
és [UnsupportedOSPlatform]
attribútumokat. Ebben az esetben a következő szabályok érvényesek:
- Lista engedélyezése. Ha az egyes operációsrendszer-platformok legalacsonyabb verziója egy
[SupportedOSPlatform]
attribútum, az API-t csak a felsorolt platformok támogatják, és az összes többi platform nem támogatja. A lista rendelkezhet[UnsupportedOSPlatform]
ugyanahhoz a platformhoz tartozó attribútummal, de csak magasabb verzióval, amely azt jelzi, hogy az API el lett távolítva az adott verzióból. - Megtagadási lista. Ha az egyes operációsrendszer-platformok legalacsonyabb verziója egy
[UnsupportedOSPlatform]
attribútum, akkor az API-t csak a felsorolt platformok nem támogatják, és az összes többi platform támogatja. A lista rendelkezhet[SupportedOSPlatform]
ugyanahhoz a platformhoz tartozó attribútummal, de csak magasabb verzióval, ami azt jelzi, hogy az API támogatott az adott verzió óta. - Inkonzisztens lista. Ha egyes platformok legalacsonyabb verziója,
[SupportedOSPlatform]
de[UnsupportedOSPlatform]
más platformok esetében ez a kombináció inkonzisztensnek minősül. A rendszer figyelmen kívül hagy néhány megjegyzést az API-n. A jövőben bevezethetünk egy elemzőt, amely inkonzisztencia esetén figyelmeztetést ad elő.
Ha egy másik platform környezetéből éri el az ezekkel az attribútumokkal jegyzett API-t, ca1416-szabálysértéseket láthat.
TFM-célplatformok
Az elemző nem ellenőrzi a cél-keretrendszer-moniker (TFM) célplatformokat az MSBuild tulajdonságokból, például <TargetFramework>
vagy <TargetFrameworks>
. Ha a TFM rendelkezik célplatformmal, a .NET SDK egy attribútumot injektál SupportedOSPlatform
a célplatform nevével a AssemblyInfo.cs fájlba, amelyet az elemző használ. Ha például a TFM aznet5.0-windows10.0.19041
, az SDK az attribútumot a AssemblyInfo.cs fájlba injektálja[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")]
, és a teljes szerelvény csak Windows-nak minősül. Ezért a csak a 7.0-s vagy újabb verziójú Windows API-k meghívása nem okoz figyelmeztetést a projektben.
Feljegyzés
Ha a AssemblyInfo.cs fájlgenerálás le van tiltva a projektben (azaz a <GenerateAssemblyInfo>
tulajdonság false
értéke), a szükséges szerelvényszintű SupportedOSPlatform
attribútumot az SDK nem tudja hozzáadni. Ebben az esetben a platformspecifikus API-k használatára vonatkozó figyelmeztetések akkor is megjelenhetnek, ha a platformot célozza. A figyelmeztetések feloldásához engedélyezze a AssemblyInfo.cs fájlgenerálást, vagy adja hozzá manuálisan az attribútumot a projekthez.
Megsértése
Ha olyan API-t ér el, amely csak egy adott platformon (
[SupportedOSPlatform("platformName")]
) érhető el más platformokon elérhető kódból, a következő szabálysértést fogja tapasztalni: Az "API" támogatott a "platformNév" szolgáltatásban.// 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. }
Feljegyzés
A szabálysértés csak akkor fordul elő, ha a projekt nem a támogatott platformot (
net5.0-differentPlatform
) célozza. Ez a többcélú projektekre is vonatkozik. Nem történik szabálysértés, ha a projekt a megadott platformra (net5.0-platformName
) irányul, és a AssemblyInfo.cs fájllétrehozás engedélyezve van a projekt számára.A nem támogatott platformot célzó környezetből hozzárendelt
[UnsupportedOSPlatform("platformName")]
API-k elérése szabálysértést okozhat: az "API" nem támogatott a platformnéven.// 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 }
Feljegyzés
Ha olyan alkalmazást készít, amely nem a nem támogatott platformot célozza meg, akkor nem fog megsérteni. A szabálysértés csak a következő esetekben fordul elő:
A projekt a nem támogatottnak tulajdonított platformot célozza meg.
Ez
platformName
az alapértelmezett MSBuild<SupportedPlatform>
elemcsoport része.platformName
manuálisan szerepel az MSBuild<SupportedPlatform>
elemek csoportjában.<ItemGroup> <SupportedPlatform Include="platformName" /> </ItemGroup>
Szabálysértések kijavítása
A szabálysértések kezelésének ajánlott módja annak biztosítása, hogy csak platformspecifikus API-kat hívjon meg, amikor megfelelő platformon fut. Ezt úgy érheti el, hogy kizárja a kódot a buildelési időpontból #if
, és több célzást alkalmaz, vagy feltételesen meghívja a kódot futásidőben. Az elemző felismeri a platformőröket az osztályban és System.Runtime.InteropServices.RuntimeInformation.IsOSPlatforma OperatingSystem .
A szabálysértések elhárításához használja a híváswebhelyet a szabványos platformőrző módszerekkel vagy az egyéni védő API-kkal vagy a SupportedOSPlatformGuardAttributeUnsupportedOSPlatformGuardAttribute.
// 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 } }
Az elemző emellett a kód nem támogatott platformokon való elérésének megakadályozására szolgáló eszközként is tiszteli System.Diagnostics.Debug.Assert . A használat
Debug.Assert
lehetővé teszi az ellenőrzés kivágását a kiadási buildek közül, ha szükséges.// An API supported only on Linux. [SupportedOSPlatform("linux")] public void LinuxOnlyApi() { } public void Caller() { Debug.Assert(OperatingSystem.IsLinux()); LinuxOnlyApi(); // No diagnostic }
Dönthet úgy, hogy saját API-jait platformspecifikusként jelöli meg, és hatékonyan továbbítja a hívóinak a követelményeket. Platformattribútumokat az alábbi API-k bármelyikére alkalmazhat:
- Típusok
- Tagok (metódusok, mezők, tulajdonságok és események)
- Szerelvények
[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 }
Szerelvényszintű vagy típusszintű attribútum alkalmazásakor a rendszer platformspecifikusnak tekinti a szerelvényen vagy típuson belüli összes tagot.
[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 } } }
Mikor kell letiltani a figyelmeztetéseket?
Nem ajánlott platformspecifikus API-kra hivatkozni megfelelő platformkörnyezet vagy védőkörnyezet nélkül. Ezeket a diagnosztikákat azonban letilthatja a NoWarn fordítójelölőjével #pragma
vagy a szabály súlyosságának none
.editorconfig fájlban való beállításával.
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }
public void Caller()
{
#pragma warning disable CA1416
LinuxOnlyApi();
#pragma warning restore CA1416
}
Kód konfigurálása elemzéshez
Az elemző alapértelmezés szerint csak a .NET 5 vagy újabb verziót megcélzó és 5 vagy újabb AnalysisLevelet használó projektek esetében engedélyezett. Az alábbi kulcs-érték párok a projekt .editorconfig fájljához való hozzáadásával engedélyezheti a cél-keretrendszerek net5.0
esetében:
dotnet_code_quality.enable_platform_analyzer_on_pre_net5_target = true
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: