Platformkompatibilitás-elemző
Valószínűleg már hallotta a "One .NET" mottóját: egyetlen, egységes platform bármilyen típusú alkalmazás létrehozásához. A .NET 5 SDK tartalmazza a ASP.NET Core, az Entity Framework Core, a WinForms, a WPF, a Xamarin és a ML.NET-et, és idővel további platformok támogatását is biztosítja. A .NET 5 arra törekszik, hogy olyan élményt nyújtson, amelyben nem kell érvelnie a .NET különböző ízei miatt, de nem kísérli meg teljesen absztrakcióval eltávolodni a mögöttes operációs rendszertől (OS). Továbbra is meghívhat platformspecifikus API-kat, például P/Invokes, WinRT vagy xamarin kötéseket iOS és Android rendszeren.
A platformspecifikus API-k egy összetevőn való használata azonban azt jelenti, hogy a kód már nem működik az összes platformon. Ezt a tervezéskor kellett észlelni, hogy a fejlesztők diagnosztikát kapjanak, amikor véletlenül platformspecifikus API-kat használnak. E cél elérése érdekében a .NET 5 bevezeti a platformkompatibilitás-elemzőt és a kiegészítő API-kat, amelyek segítenek a fejlesztőknek adott esetben a platformspecifikus API-k azonosításában és használatában.
Az új API-k a következők:
- SupportedOSPlatformAttribute az API-k platformspecifikusként történő jegyzetelése, valamint UnsupportedOSPlatformAttribute az API-k megjegyzésekkel való ellátása, mivel az adott operációs rendszeren nem támogatottak. Ezek az attribútumok opcionálisan tartalmazhatják a verziószámot, és már alkalmazva lettek néhány platformspecifikus API-ra az alapvető .NET-kódtárakban.
Is<Platform>()
ésIs<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
statikus metódusok az System.OperatingSystem osztályban a platformspecifikus API-k biztonságos meghívásához. Például OperatingSystem.IsWindows() egy Windows-specifikus API-ra irányuló hívások őrzésére használható, és OperatingSystem.IsWindowsVersionAtLeast() egy verziószámozott Windows-specifikus API-hívás őrzésére. Tekintse meg ezeket a példákat, amelyek bemutatja, hogyan használhatók ezek a metódusok platformspecifikus API-referenciák őreiként.
Előfeltételek
A platformkompatibilitás-elemző a Roslyn-kódminőség-elemzők egyike. A .NET 5-tel kezdődően ezek az elemzők a .NET SDK részét képezik. A platformkompatibilitás-elemző alapértelmezés szerint csak a megcélzott net5.0
vagy újabb verziójú projektek esetében engedélyezett. Azonban más keretrendszereket célzó projektekhez is engedélyezheti .
Hogyan határozza meg az elemző a platformfüggőséget?
A nem felügyelt API-kminden operációsrendszer-platformon működnek.
A megjelölt
[SupportedOSPlatform("platform")]
API-k csak a megadott platformon hordozhatónak tekinthetők, és minden olyan platformon, amelynek az alkészlete.- Az attribútum többször is alkalmazható több platform támogatásának jelzésére, például
[SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")]
. - Ha a platform egy másik platform részhalmaza, az attribútum azt jelenti, hogy a szuperhalmazplatform is támogatott. Ez például azt jelenti,
[SupportedOSPlatform("iOS")]
hogy az API a superset platformoniOS
is támogatott.MacCatalyst
- Az elemző figyelmeztetést küld, ha a platformspecifikus API-kra megfelelő platformkörnyezet nélkül hivatkoznak:
- Figyelmeztet, ha a projekt nem a támogatott platformot célozza (például egy iOS-t
<TargetFramework>net5.0-ios14.0</TargetFramework>
célzó projektből hívott Windows-specifikus API-t). - Figyelmeztet, ha a projekt platformfüggetlen, és platformspecifikus API-kat hív meg (például egy platformfüggetlen TFM-ből
<TargetFramework>net5.0</TargetFramework>
hívott Windows-specifikus API-t). - Nem figyelmeztet, ha a platformspecifikus API-ra hivatkozik egy olyan projektben, amely a megadott platformok bármelyikét célozza (például egy olyan Windows-specifikus API esetében, amely egy olyan projektből van meghívva, amely windowsos
<TargetFramework>net5.0-windows</TargetFramework>
, és a AssemblyInfo.cs fájlgenerálás engedélyezve van a projekthez). - Nem figyelmeztet, ha a platformspecifikus API-hívást a megfelelő platformellenőrzési módszerek (például egy Windows-specifikus API-hívás őrzi
OperatingSystem.IsWindows()
). - Nem figyelmeztet, ha a platformspecifikus API-ra ugyanabból a platformspecifikus környezetből hivatkozik (a hívási hely is hozzá van rendelve
[SupportedOSPlatform("platform")
).
- Figyelmeztet, ha a projekt nem a támogatott platformot célozza (például egy iOS-t
- Az attribútum többször is alkalmazható több platform támogatásának jelzésére, például
A megjelölt
[UnsupportedOSPlatform("platform")]
API-k nem támogatottak a megadott platformon, és az összes többi platformon is támogatottak.- Az attribútum többször is alkalmazható különböző platformokon, például
[UnsupportedOSPlatform("iOS"), UnsupportedOSPlatform("Android29.0")]
. - Ha a platform egy másik platform részhalmaza, az attribútum azt jelenti, hogy a szuperhalmazplatform szintén nem támogatott. Ez azt jelenti például,
[UnsupportedOSPlatform("iOS")]
hogy az API nem támogatott aiOS
superset platformon és annak superset platformján is.MacCatalyst
- Az elemző csak akkor állít elő figyelmeztetést , ha a
platform
hívási hely érvényes:Figyelmezteti , ha a projekt a nem támogatottnak tulajdonított platformot célozza meg (például ha az API attribútuma
[UnsupportedOSPlatform("windows")]
és a hívási hely céljai<TargetFramework>net5.0-windows</TargetFramework>
).Figyelmezteti , ha a projekt több célzott, és az
platform
alapértelmezett MSBuild<SupportedPlatform>
elemcsoport része, vagy manuálisan szerepel aplatform
MSBuild
<Támogatottplatform-elemek> csoportban:<ItemGroup> <SupportedPlatform Include="platform" /> </ItemGroup>
Nem figyelmeztet , ha olyan alkalmazást készít, amely nem a nem támogatott platformot célozza, vagy több-célzott, és a platform nem szerepel az alapértelmezett MSBuild
<SupportedPlatform>
elemek csoportjában.
- Az attribútum többször is alkalmazható különböző platformokon, például
Mindkét attribútum példányosítható verziószámokkal vagy anélkül a platformnév részeként. A verziószámok formátuma
major.minor[.build[.revision]]
;major.minor
kötelező, és azbuild
revision
alkatrészek nem kötelezőek. A "Windows6.1" például azt jelzi, Windows 6.1-es verziót, de a "Windows" Windows 0.0-s verzióként van értelmezve.
További információkért tekintse meg az attribútumok működését és az általuk okozott diagnosztikát.
Hogyan ismeri fel az elemző a TFM-célplatformokat?
Az elemző nem ellenőrzi a célkeret-moniker (TFM) célplatformokat az MSBuild tulajdonságokból, például <TargetFramework>
vagy <TargetFrameworks>
. Ha a TFM célplatformmal rendelkezik, az MSBuild egy attribútumot szúr be SupportedOSPlatform
a megcélzott platform nevével a AssemblyInfo.cs fájlba, amelyet az elemző használ fel. Ha például a TFM aznet5.0-windows10.0.19041
, az MSBuild beszúrja az [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")]
attribútumot a AssemblyInfo.cs fájlba, és a teljes szerelvény csak Windows. Ezért a Windows csak 7.0-s vagy újabb verziójú API-k meghívása nem okozna figyelmeztetést a projektben.
Megjegyzés
Ha a AssemblyInfo.cs fájl létrehozása le van tiltva a projekthez (azaz a <GenerateAssemblyInfo>
tulajdonság értéke false
), az MSBuild nem tudja hozzáadni a szükséges szerelvényszintű SupportedOSPlatform
attribútumot. Ebben az esetben a platformspecifikus API-k használatára vonatkozó figyelmeztetések akkor is megjelenhetnek, ha ezt 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.
Platformbefoglalás
A .NET 6 bevezeti a platformbefoglalás fogalmát, ahol az egyik platform egy másik platform részhalmaza lehet. Az alhalmazplatformhoz tartozó széljegyzetek a szuperhalmazplatform ugyanazon támogatását (vagy annak hiányát) jelentik. Ha a típusban egy OperatingSystem platformellenőrzési metódus rendelkezik SupportedOSPlatformGuard("supersetPlatform")]
attribútummal, akkor supersetPlatform
a rendszer az operációsrendszer-platform azon szuperhalmazának tekinti, amelyet a metódus ellenőriz.
A metódus attribútuma [SupportedOSPlatformGuard("MacCatalyst")]
például OperatingSystem.IsIOS() . Ezért a következő állítások érvényesek:
- A OperatingSystem.IsIOS() metódusok nemcsak OperatingSystem.IsIOSVersionAtLeast a platformot, hanem a
iOS
platformot is ellenőrzikMacCatalyst
. [SupportedOSPlatform("iOS")]
azt jelenti, hogy az API a superset platformoniOS
és annak platformján is támogatott,MacCatalyst
. Az attribútummal kizárhatja ezt a[UnsupportedOSPlatform("MacCatalyst")]
vélelmezett támogatást.[UnsupportedOSPlatform("iOS")
azt jelenti, hogy az API nem támogatott,iOS
ésMacCatalyst
. Az attribútum használatával kizárhatja ezt a[SupportedOSPlatform("MacCatalyst")]
vélelmezett támogatáshiányt.
Vegye figyelembe a következő lefedettségi mátrixot, amely ✔️ azt jelzi, hogy a platform támogatott, és ❌ azt jelzi, hogy a platform nem támogatott.
Platform | SupportedOSPlatform(subset) |
SupportedOSPlatform(superset) |
UnsupportedOSPlatform(subset) |
UnsupportedOSPlatform(superset) |
---|---|---|---|---|
Részhalmazát | ✔️ | ❌ | ✔️ | ❌ |
Felülbírálja | ✔️ | ✔️ | ✔️ | ✔️ |
Tipp
Ugyanezek a szabályok vonatkoznak az és UnsupportedOSPlatformGuard
az SupportedOSPlatformGuard
attribútumokra is.
Az alábbi kódrészlet bemutatja, hogyan kombinálhatja az attribútumokat a megfelelő támogatási szint beállításához.
// MacCatalyst is a superset of iOS therefore supported on iOS and MacCatalyst
[SupportedOSPlatform("iOS")]
public void ApiOnlySupportedOnIOSAndMacCatalyst() { }
// Does not imply iOS, only supported on MacCatalyst
[SupportedOSPlatform("MacCatalyst")]
public void ApiOnlySupportedOnMacCatalyst() { }
[SupportedOSPlatform("iOS")] // Supported on iOS and MacCatalyst
[UnsupportedOSPlatform("MacCatalyst")] // Removes implied MacCatalyst support
public void ApiOnlySupportedOnIos() { }
// Unsupported on iOS and MacCatalyst
[UnsupportedOSPlatform("iOS")]
public void ApiUnsupportedOnIOSAndMacCatalyst();
// Does not imply iOS, only unsupported on MacCatalyst
[UnsupportedOSPlatform("MacCatalyst")]
public void ApiUnsupportedOnMacCatalyst() { }
[UnsupportedOSPlatform("iOS")] // Unsupported on iOS and MacCatalyst
[SupportedOSPlatform("MacCatalyst")] // Removes implied MacCatalyst unsupportedness
public void ApiUnsupportedOnIos() { }
Speciális forgatókönyvek attribútumkombinációkhoz
Ha az attribútumok és
[UnsupportedOSPlatform]
az[SupportedOSPlatform]
attribútumok kombinációja van jelen, az összes attribútum az operációs rendszer platformazonosítója szerint van csoportosítva:Csak támogatott lista. 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. Az egyes platformok opcionális[UnsupportedOSPlatform]
attribútumai csak a minimálisan támogatott verzió magasabb verziójával rendelkezhetnek, ami azt jelzi, hogy az API a megadott verziótól kezdve el lett távolítva.// API is only supported on Windows from version 6.2 to 10.0.19041.0 and all versions of Linux // The API is considered not supported for all other platforms. [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] [SupportedOSPlatform("linux")] public void ApiSupportedFromWindows80SupportFromCertainVersion();
Nem támogatott csak 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 egy magasabb verzióval, ami azt jelzi, hogy az API az adott verziótól kezdve támogatott.// The API is unsupported on all Linux versions was unsupported on Windows until version 10.0.19041.0. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.19041.0")] [UnsupportedOSPlatform("linux")] public void ApiSupportedFromWindows8UnsupportedFromWindows10();
Inkonzisztens lista. Ha egyes platformok
[SupportedOSPlatform]
[UnsupportedOSPlatform]
legalacsonyabb verziója más platformokhoz tartozik, akkor inkonzisztensnek minősül, ami az elemző számára nem támogatott. Inkonzisztencia esetén az elemző figyelmen kívül hagyja a[UnsupportedOSPlatform]
platformokat.- Ha az attribútumok és
[UnsupportedOSPlatform]
az[SupportedOSPlatform]
attribútumok legalacsonyabb verziói egyenlők, az elemző a platformot csak a támogatott lista részeként tekinti.
- Ha az attribútumok és
A platformattribútumok különböző platformnevekkel vagy -verziókkal rendelkező típusokra, tagokra (metódusokra, mezőkre, tulajdonságokra és eseményekre) és szerelvényekre alkalmazhatók.
- A legfelső szinten
target
alkalmazott attribútumok az összes tagot és típust érintik. - A gyermekszintű attribútumok csak akkor érvényesek, ha betartják a "gyermekjegyzetek szűkíthetik a platformok támogatását, de nem bővíthetik azt".
- Ha a szülő csak támogatott listával rendelkezik, akkor a gyermektag-attribútumok nem adhatnak hozzá új platformtámogatást, mivel ez kiterjesztené a szülőtámogatást. Az új platform támogatása csak a szülőhöz adható hozzá. A gyermek azonban rendelkezhet ugyanahhoz a
Supported
platformhoz tartozó attribútummal, amely későbbi verziókkal rendelkezik, mint ami szűkíti a támogatást. Emellett a gyermek ugyanazzal a platformmal rendelkezhet azUnsupported
attribútummal, amely a szülőtámogatást is szűkíti. - Ha a szülő nem támogatott csak listával rendelkezik, akkor a gyermektag-attribútumok támogatást adhatnak egy új platformhoz, mivel ez szűkíti a szülőtámogatást. De nem rendelkezhet ugyanazzal a
Supported
platformmal, mint a szülő, mert ez kiterjeszti a szülőtámogatást. Ugyanannak a platformnak a támogatása csak az eredetiUnsupported
attribútumot alkalmazó szülőhöz adható hozzá.
- Ha a szülő csak támogatott listával rendelkezik, akkor a gyermektag-attribútumok nem adhatnak hozzá új platformtámogatást, mivel ez kiterjesztené a szülőtámogatást. Az új platform támogatása csak a szülőhöz adható hozzá. A gyermek azonban rendelkezhet ugyanahhoz a
- Ha
[SupportedOSPlatform("platformVersion")]
többször alkalmazva van egy azonosplatform
nevű API-ra, az elemző csak a minimális verzióval rendelkezőt veszi figyelembe. - Ha
[UnsupportedOSPlatform("platformVersion")]
egy azonosplatform
nevű API-hoz kétszer több van alkalmazva, az elemző csak a legkorábbi verzióval rendelkező kettőt veszi figyelembe.
Megjegyzés
Az eredetileg támogatott, de nem támogatott (eltávolított) API-k egy későbbi verzióban várhatóan nem lesznek újra támogatottak egy még későbbi verzióban.
- A legfelső szinten
Példák az attribútumok működésére és az általuk előállított diagnosztikai adatokra
// An API supported only on Windows all versions.
[SupportedOSPlatform("Windows")]
public void WindowsOnlyApi() { }
// an API supported on Windows and Linux.
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Linux")]
public void SupportedOnWindowsAndLinuxOnly() { }
// an API only supported on Windows 6.2 and later, not supported for all other.
// an API is removed/unsupported from version 10.0.19041.0.
[SupportedOSPlatform("windows6.2")]
[UnsupportedOSPlatform("windows10.0.19041.0")]
public void ApiSupportedFromWindows8UnsupportedFromWindows10() { }
// an Assembly supported on Windows, the API added from version 10.0.19041.0.
[assembly: SupportedOSPlatform("Windows")]
[SupportedOSPlatform("windows10.0.19041.0")]
public void AssemblySupportedOnWindowsApiSupportedFromWindows10() { }
public void Caller()
{
WindowsOnlyApi(); // warns: This call site is reachable on all platforms. 'WindowsOnlyApi()' is only supported on: 'windows'
// This call site is reachable on all platforms. 'SupportedOnWindowsAndLinuxOnly()' is only supported on: 'Windows', 'Linux'
SupportedOnWindowsAndLinuxOnly();
// This call site is reachable on all platforms. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is only supported on: 'windows' from version 6.2 to 10.0.19041.0
ApiSupportedFromWindows8UnsupportedFromWindows10();
// for same platform analyzer only warn for the latest version.
// This call site is reachable on all platforms. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later
AssemblySupportedOnWindowsApiSupportedFromWindows10();
}
// an API not supported on android but supported on all other.
[UnsupportedOSPlatform("android")]
public void DoesNotWorkOnAndroid() { }
// an API was unsupported on Windows until version 6.2.
// The API is considered supported everywhere else without constraints.
[UnsupportedOSPlatform("windows")]
[SupportedOSPlatform("windows6.2")]
public void StartedWindowsSupportFromVersion8() { }
// an API was unsupported on Windows until version 6.2.
// Then the API is removed (unsupported) from version 10.0.19041.0.
// The API is considered supported everywhere else without constraints.
[UnsupportedOSPlatform("windows")]
[SupportedOSPlatform("windows6.2")]
[UnsupportedOSPlatform("windows10.0.19041.0")]
public void StartedWindowsSupportFrom8UnsupportedFrom10() { }
public void Caller2()
{
DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android'
// This call site is reachable on all platforms. 'StartedWindowsSupportFromVersion8()' is unsupported on: 'windows' 6.2 and before.
StartedWindowsSupportFromVersion8();
// This call site is reachable on all platforms. 'StartedWindowsSupportFrom8UnsupportedFrom10()' is supported on: 'windows' from version 6.2 to 10.0.19041.0
StartedWindowsSupportFrom8UnsupportedFrom10();
}
Jelentett figyelmeztetések kezelése
A diagnosztika kezelésének ajánlott módja annak biztosítása, hogy csak platformspecifikus API-kat hívjon meg, amikor egy megfelelő platformon fut. Az alábbiakban a figyelmeztetések kezelésére használható lehetőségeket találja; válassza ki a helyzetének leginkább megfelelőt:
Őrizd meg a hívást. Ezt úgy érheti el, hogy futtatáskor feltételesen meghívja a kódot. Ellenőrizze, hogy a kívánt
Platform
módon fut-e a platformellenőrzési módszerek egyikével, példáulOperatingSystem.Is<Platform>()
vagyOperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
. Példa.A hívási webhely megjelölése platformspecifikusként. Dönthet úgy is, hogy a saját API-jait platformspecifikusként jelöli meg, így hatékonyan továbbítja a követelményeket a hívóknak. Jelölje meg a tartalmazó metódust vagy típust vagy a teljes szerelvényt ugyanazokkal az attribútumokkal, mint a hivatkozott platformfüggő hívás. Példák.
Állítsd be a hívási webhelyet platformellenőrzéssel. Ha nem szeretné a további
if
utasítások többletterhelését futásidőben elvégezni, használja a következőt Debug.Assert(Boolean): . Példa.Törölje a kódot. Általában nem az, amit szeretne, mert ez azt jelenti, hogy elveszíti a pontosságot, amikor a kódot Windows felhasználók használják. Platformfüggetlen alternatíva esetén érdemesebb ezt platformspecifikus API-kkal használni.
A figyelmeztetés mellőzése. A figyelmeztetést egyszerűen letilthatja egy EditorConfig bejegyzéssel vagy
#pragma warning disable CA1416
. Ennek a lehetőségnek azonban végső megoldásnak kell lennie platformspecifikus API-k használatakor.Tipp
Ha az előfordító irányelvekkel letiltja a
#pragma
figyelmeztetéseket, a megcélzott azonosítók megkülönböztetik a kis- és nagybetűket. Példáulca1416
nem tiltaná le a CA1416 figyelmeztetést.
Platformspecifikus API-k őrzési módszerekkel
A guard metódus platformnevének meg kell egyeznie a hívó platformtól függő API-platform nevével. Ha a hívó API platformsztringje tartalmazza a verziót:
Az attribútum esetében a
[SupportedOSPlatform("platformVersion")]
guard metódusplatformnakversion
nagyobbnak vagy egyenlőnek kell lennie, mint a hívó platforméVersion
.Az attribútum esetében a
[UnsupportedOSPlatform("platformVersion")]
guard metódus platformjánakversion
kisebbnek vagy egyenlőnek kell lennie, mint a hívó platforméVersion
.public void CallingSupportedOnlyApis() // Allow list calls { if (OperatingSystem.IsWindows()) { WindowsOnlyApi(); // will not warn } if (OperatingSystem.IsLinux()) { SupportedOnWindowsAndLinuxOnly(); // will not warn, within one of the supported context } // Can use &&, || logical operators to guard combined attributes if (OperatingSystem.IsWindowsVersionAtLeast(6, 2) && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))) { ApiSupportedFromWindows8UnsupportedFromWindows10(); } if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041, 0)) { AssemblySupportedOnWindowsApiSupportedFromWindows10(); // Only need to check latest supported version } } public void CallingUnsupportedApis() { if (!OperatingSystem.IsAndroid()) { DoesNotWorkOnAndroid(); // will not warn } if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(6, 2)) { StartedWindowsSupportFromVersion8(); // will not warn } if (!OperatingSystem.IsWindows() || // supported all other platforms (OperatingSystem.IsWindowsVersionAtLeast(6, 2) && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))) { StartedWindowsSupportFrom8UnsupportedFrom10(); // will not warn } }
Ha meg kell őriznie a célkódokat
netstandard
, vagynetcoreapp
ha az új OperatingSystem API-k nem érhetők el, az RuntimeInformation.IsOSPlatform API használható, és az elemző figyelembe fogja venni. Ez azonban nem olyan optimalizált, mint az új API-k.OperatingSystem Ha a struktúra nem támogatja a OSPlatform platformot, meghívhatja OSPlatform.Create(String) és átadhatja a platform nevét, amelyet az elemző is tiszteletben tart.public void CallingSupportedOnlyApis() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { SupportedOnWindowsAndLinuxOnly(); // will not warn } if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("browser"))) { ApiOnlySupportedOnBrowser(); // call of browser specific API } }
Api-k megjegyzésekkel való ellátása platformőr-attribútumokkal, és egyéni védőként való használata
Ahogy korábban láthattuk, az elemző felismeri a platformőr statikus metódusokat a OperatingSystem típusban, például OperatingSystem.IsWindows
a .RuntimeInformation.IsOSPlatform Előfordulhat azonban, hogy gyorsítótárazni szeretné a védőeredményt egy mezőben, és újra fel szeretné használni, vagy egyéni védelmi módszereket szeretne használni a platform ellenőrzéséhez. Az elemzőnek egyéni védőként kell felismernie az ilyen API-kat, és nem szabad figyelmeztetnie az általuk védett API-kat. A védőattribútumokat a .NET 6-ban vezettük be, hogy támogassa ezt a forgatókönyvet:
SupportedOSPlatformGuardAttribute
A jegyzetekkel láthatja el az API-k védőjeként használható API-kat SupportedOSPlatformAttribute.UnsupportedOSPlatformGuardAttribute
A jegyzetekkel láthatja el az API-k védőjeként használható API-kat UnsupportedOSPlatformAttribute.
Ezek az attribútumok tartalmazhatnak verziószámot is. Többször is alkalmazhatók több platform őrzésére, és mező, tulajdonság vagy metódus megjegyzésekkel való ellátásához használhatók.
class Test
{
[UnsupportedOSPlatformGuard("browser")] // The platform guard attribute
#if TARGET_BROWSER
internal bool IsSupported => false;
#else
internal bool IsSupported => true;
#endif
[UnsupportedOSPlatform("browser")]
void ApiNotSupportedOnBrowser() { }
void M1()
{
ApiNotSupportedOnBrowser(); // Warns: This call site is reachable on all platforms.'ApiNotSupportedOnBrowser()' is unsupported on: 'browser'
if (IsSupported)
{
ApiNotSupportedOnBrowser(); // Not warn
}
}
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Linux")]
void ApiOnlyWorkOnWindowsLinux() { }
[SupportedOSPlatformGuard("Linux")]
[SupportedOSPlatformGuard("Windows")]
private readonly bool _isWindowOrLinux = OperatingSystem.IsLinux() || OperatingSystem.IsWindows();
void M2()
{
ApiOnlyWorkOnWindowsLinux(); // This call site is reachable on all platforms.'ApiOnlyWorkOnWindowsLinux()' is only supported on: 'Linux', 'Windows'.
if (_isWindowOrLinux)
{
ApiOnlyWorkOnWindowsLinux(); // Not warn
}
}
}
Híváswebhely megjelölése platformspecifikusként
A platformneveknek meg kell egyeznie a hívó platformtól függő API-val. Ha a platform sztringje tartalmaz verziót:
Az attribútum esetében a
[SupportedOSPlatform("platformVersion")]
hívási hely platformjánakversion
nagyobbnak vagy egyenlőnek kell lennie, mint a hívóplatforméVersion
Az attribútum esetében a
[UnsupportedOSPlatform("platformVersion")]
hívási hely platformjánakversion
kisebbnek vagy egyenlőnek kell lennie, mint a hívóplatforméVersion
// an API supported only on Windows. [SupportedOSPlatform("windows")] public void WindowsOnlyApi() { } // an API supported on Windows and Linux. [SupportedOSPlatform("Windows")] [SupportedOSPlatform("Linux")] public void SupportedOnWindowsAndLinuxOnly() { } // an API only supported on Windows 6.2 and later, not supported for all other. // an API is removed/unsupported from version 10.0.19041.0. [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] public void ApiSupportedFromWindows8UnsupportedFromWindows10() { } // an Assembly supported on Windows, the API added from version 10.0.19041.0. [assembly: SupportedOSPlatform("Windows")] [SupportedOSPlatform("windows10.0.19041.0")] public void AssemblySupportedOnWindowsApiSupportedFromWindows10() { } [SupportedOSPlatform("windows6.2")] // call site attributed Windows 6.2 or above. public void Caller() { WindowsOnlyApi(); // will not warn as call site is for Windows. // will not warn as call site is for Windows all versions. SupportedOnWindowsAndLinuxOnly(); // will not warn for the [SupportedOSPlatform("windows6.2")] attribute, but warns for [UnsupportedOSPlatform("windows10.0.19041.0")] // This call site is reachable on: 'windows' 6.2 and later. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later. ApiSupportedFromWindows8UnsupportedFromWindows10(); // The call site version is lower than the calling version, so warns: // This call site is reachable on: 'windows' 6.2 and later. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later AssemblySupportedOnWindowsApiSupportedFromWindows10(); } [SupportedOSPlatform("windows10.0.22000")] // call site attributed with windows 10.0.22000 or above. public void Caller2() { // This call site is reachable on: 'windows' 10.0.22000 and later. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later. ApiSupportedFromWindows8UnsupportedFromWindows10(); // will not warn as call site version higher than calling API. AssemblySupportedOnWindowsApiSupportedFromWindows10(); } [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] // call site supports Windows from version 6.2 to 10.0.19041.0. public void Caller3() { // will not warn as caller has exact same attributes. ApiSupportedFromWindows8UnsupportedFromWindows10(); // The call site reachable for the version not supported in the calling API, therefore warns: // This call site is reachable on: 'windows' from version 6.2 to 10.0.19041.0. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later. AssemblySupportedOnWindowsApiSupportedFromWindows10(); } // an API not supported on Android but supported on all other. [UnsupportedOSPlatform("android")] public void DoesNotWorkOnAndroid() { } // an API was unsupported on Windows until version 6.2. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows6.2")] public void StartedWindowsSupportFromVersion8() { } // an API was unsupported on Windows until version 6.2. // Then the API is removed (unsupported) from version 10.0.19041.0. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] public void StartedWindowsSupportFrom8UnsupportedFrom10() { } [UnsupportedOSPlatform("windows")] // Caller no support Windows for any version. public void Caller4() { // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android' DoesNotWorkOnAndroid(); // will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFromVersion8(); // same, will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFrom8UnsupportedFrom10(); } [UnsupportedOSPlatform("windows")] [UnsupportedOSPlatform("android")] // Caller not support Windows and Android for any version. public void Caller4() { DoesNotWorkOnAndroid(); // will not warn as call site not supports Android. // will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFromVersion8(); // same, will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFrom8UnsupportedFrom10(); }
A hívási hely érvényesítése platformellenőrzéssel
A platformőr példáiban használt összes feltételes ellenőrzés használható feltételként Debug.Assert(Boolean)is.
// An API supported only on Linux.
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }
public void Caller()
{
Debug.Assert(OperatingSystem.IsLinux());
LinuxOnlyApi(); // will not warn
}