平台相容性分析器
您可能聽過「一個 .NET」的名詞:單一、統一的平臺,用於建置任何類型的應用程式。 .NET 5 SDK 包含 ASP.NET Core、Entity Framework Core、WinForms、WPF、Xamarin 和 ML.NET,並隨著時間新增更多平臺的支援。 .NET 5 致力於提供一個體驗,因為您不需要對不同類別 .NET 產生理由,但不會嘗試完全抽象化基礎作業系統 (OS) 。 您將能夠繼續呼叫平臺特定的 API,例如 P/Invokes、WinRT 或適用于 iOS 和 Android 的 Xamarin 系結。
但是,在元件上使用平臺特定 API 表示程式碼無法再在所有平臺上運作。 我們需要在設計階段偵測此情況的方法,讓開發人員在不小心使用平臺特定 API 時取得診斷。 為了達成此目標,.NET 5 引進 了平臺相容性分析器和 互補 API,以協助開發人員在適當情況下識別及使用平臺特定 API。
新的 API 包括:
- SupportedOSPlatformAttribute 將 API 批註為平臺特定,並將 UnsupportedOSPlatformAttribute API 批註為特定 OS 不支援。 這些屬性可以選擇性地包含版本號碼,並已套用至核心 .NET 程式庫中的某些平臺特定 API。
Is<Platform>()
和Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
類別中的 System.OperatingSystem 靜態方法,用於安全地呼叫平臺特定 API。 例如, OperatingSystem.IsWindows() 可用來保護對Windows特定 API 的呼叫,而 OperatingSystem.IsWindowsVersionAtLeast () 可用來保護版本化Windows特定 API 呼叫。 請參閱這些 範例 ,以瞭解這些方法如何作為平臺特定 API 參考的防護。
必要條件
平臺相容性分析器是其中一個 Roslyn 程式碼品質分析器。 從 .NET 5 開始,這些分析器 會隨附于 .NET SDK中。 平臺相容性分析器預設只會針對目標 net5.0
或更新版本的專案啟用。 不過,您可以針對以其他架構為目標的專案 啟用它 。
分析器如何判斷平臺相依性
未設定的 API會被視為在所有作業系統平臺上運作。
標示為 的
[SupportedOSPlatform("platform")]
API 只會被視為可移植到指定的平臺,以及其為子集的任何平臺。- 屬性可以多次套用,以指出 多個平臺支援,例如
[SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")]
。 - 如果平臺是 另一個平臺的子集,屬性工作表示也支援超集合平臺。 例如,
[SupportedOSPlatform("iOS")]
表示 API 也在其iOS
超集合平臺上受到支援。MacCatalyst
- 如果在沒有適當的平臺內容的情況下參考平臺特定 API,分析器將會產生警告:
- 例如,如果專案未以支援的平臺為目標, (發出警告,例如,從以 iOS
<TargetFramework>net5.0-ios14.0</TargetFramework>
) 為目標的專案呼叫的Windows特定 API。 - 例如,如果專案是跨平臺且呼叫平臺特定 API (,則發出警告,例如,從跨平臺 TFM
<TargetFramework>net5.0</TargetFramework>
) 呼叫的Windows特定 API。 - 例如,如果以任何指定平臺為目標的專案內參考平臺特定 API (,則不會發出警告,例如,針對從專案目標視窗
<TargetFramework>net5.0-windows</TargetFramework>
呼叫的Windows特定 API,且已針對專案) 啟用AssemblyInfo.cs檔案產生。 - 如果平臺特定 API 呼叫受到對應的平臺檢查方法所防護 (,則不會發出警告,例如,由) 所防護
OperatingSystem.IsWindows()
的Windows特定 API 呼叫。 - 如果從相同的平臺特定內容參考平臺特定 API, (呼叫月臺也會使用
[SupportedOSPlatform("platform")
) 來參考,則不會發出警告。
- 例如,如果專案未以支援的平臺為目標, (發出警告,例如,從以 iOS
- 屬性可以多次套用,以指出 多個平臺支援,例如
標示為
[UnsupportedOSPlatform("platform")]
的 API 在指定的平臺上被視為不受支援,且其為子集的任何平臺,但支援所有其他平臺。- 屬性可以使用不同的平臺多次套用,
[UnsupportedOSPlatform("iOS"), UnsupportedOSPlatform("Android29.0")]
例如 。 - 如果平臺是 另一個平臺的子集,屬性工作表示超集合平臺也不受支援。 例如,
[UnsupportedOSPlatform("iOS")]
表示 API 不受支援iOS
,也在其超集合平臺上為MacCatalyst
。 - 只有當 對呼叫月臺有效時
platform
,分析器才會產生警告:例如,如果專案以屬性化為不支援 (的平臺為目標,則發出警告,例如,如果 API 是以 屬性化
[UnsupportedOSPlatform("windows")]
,且呼叫網站目標<TargetFramework>net5.0-windows</TargetFramework>
) 。如果專案是多目標專案,且
platform
包含在預設MSBuild<SupportedPlatform>
專案群組中,或platform
手動包含在 SupportedPlatform > 專案群組中MSBuild
< ,就會發出警告:<ItemGroup> <SupportedPlatform Include="platform" /> </ItemGroup>
如果您要建置的應用程式不是以不支援的平臺為目標,或是多重目標,且平臺未包含在預設MSBuild
<SupportedPlatform>
專案群組中,則不會發出警告。
- 屬性可以使用不同的平臺多次套用,
這兩個屬性都可以使用或不含版本號碼來具現化,作為平臺名稱的一部分。 版本號碼的格式
major.minor[.build[.revision]]
為 ;major.minor
為必要專案,build
且 和revision
元件為選擇性。 例如,「Windows6.1」 表示Windows 6.1 版,但 「Windows」 會解譯為 Windows 0.0。
如需詳細資訊,請參閱 屬性的運作方式和其造成診斷的範例。
分析器如何辨識 TFM 目標平臺
分析器不會從 MSBuild 屬性檢查目標 Framework Moniker (TFM) 目標平臺,例如 <TargetFramework>
或 <TargetFrameworks>
。 如果 TFM 有目標平臺,MSBuild SupportedOSPlatform
會在分析器取用的AssemblyInfo.cs檔案中插入具有目標平臺名稱的屬性。 例如,如果 TFM 為 net5.0-windows10.0.19041
,MSBuild將 [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")]
屬性插入AssemblyInfo.cs檔案中,而且整個元件只會被視為Windows。 因此,呼叫以 7.0 或以下版本建立的僅限Windows API 並不會在專案中造成任何警告。
注意
如果專案 (停用AssemblyInfo.cs檔案產生, <GenerateAssemblyInfo>
則屬性會設定為 false
) ,MSBuild就無法新增必要的元件層級 SupportedOSPlatform
屬性。 在此情況下,即使以平臺為目標,您仍會看到平臺特定 API 使用量的警告。 若要解決警告,請啟用 AssemblyInfo.cs 檔案產生,或在專案中手動新增 屬性。
平臺包含
.NET 6 引進 了平臺包含的概念,其中一個平臺可以是另一個平臺的子集。 子集平臺的批註表示 (或缺少超集合平臺) 相同的支援。 如果型別中的 OperatingSystem 平臺檢查方法具有 SupportedOSPlatformGuard("supersetPlatform")]
屬性,則會 supersetPlatform
被視為方法所檢查 OS 平臺的超集合。
例如,方法是 OperatingSystem.IsIOS() 屬性化 [SupportedOSPlatformGuard("MacCatalyst")]
。 因此,適用下列語句:
- OperatingSystem.IsIOS()和 OperatingSystem.IsIOSVersionAtLeast 方法不僅
iOS
會檢查平臺,也會MacCatalyst
檢查平臺。 [SupportedOSPlatform("iOS")]
表示 API 在 和 其超集合平臺上也支援iOS
。MacCatalyst
您可以使用[UnsupportedOSPlatform("MacCatalyst")]
屬性來排除此隱含支援。[UnsupportedOSPlatform("iOS")
表示 和MacCatalyst
不支援iOS
API。 您可以使用[SupportedOSPlatform("MacCatalyst")]
屬性來排除此隱含缺少支援。
請考慮下列涵蓋範圍矩陣,其中 ✔️ 表示支援平臺,並 ❌ 指出 不支援 平臺。
平台 | SupportedOSPlatform(subset) |
SupportedOSPlatform(superset) |
UnsupportedOSPlatform(subset) |
UnsupportedOSPlatform(superset) |
---|---|---|---|---|
Subset | ✔️ | ❌ | ✔️ | ❌ |
超集合 | ✔️ | ✔️ | ✔️ | ✔️ |
提示
相同的規則適用于 SupportedOSPlatformGuard
和 UnsupportedOSPlatformGuard
屬性。
下列程式碼片段示範如何結合屬性來設定正確的支援層級。
// 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() { }
屬性組合的進階案例
如果 和
[UnsupportedOSPlatform]
屬性的組合[SupportedOSPlatform]
存在,所有屬性都會依 OS 平臺識別碼分組:僅支援清單。 如果每個 OS 平臺的最低版本是
[SupportedOSPlatform]
屬性,則 API 只會被列出的平臺支援,而且所有其他平臺都不支援。 每個平臺的選擇性[UnsupportedOSPlatform]
屬性只能有較高版本的最低支援版本,這表示從指定的版本開始移除 API。// 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();
僅限不支援的清單。 如果每個 OS 平臺的最低版本是
[UnsupportedOSPlatform]
屬性,則 API 只會被列出的平臺支援,並受到所有其他平臺支援。 清單可以有[SupportedOSPlatform]
相同平臺的屬性,但版本較高,這表示從該版本開始支援 API。// 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();
不一致的清單。 如果某些平臺的最低版本是
[SupportedOSPlatform]
[UnsupportedOSPlatform]
針對其他平臺,則被視為不一致,分析器不支援此版本。 如果發生不一致的情況,分析器會[UnsupportedOSPlatform]
忽略平臺。- 如果 和
[UnsupportedOSPlatform]
屬性的最低版本[SupportedOSPlatform]
相等,分析器會將平臺視為僅支援清單的一部分。
- 如果 和
平臺屬性可以套用至具有不同平臺名稱或版本的類型、成員 (方法、欄位、屬性和事件) 和元件。
- 最上層
target
套用的屬性會影響其所有成員和類型。 - 子層級屬性僅適用于遵守規則「子批註可以縮小平臺支援範圍,但無法擴大它」的規則。
- 當父系 僅支援 清單時,子成員屬性就無法加入新的平臺支援,因為這樣會擴充父支援。 新平臺的支援只能新增至父代本身。 但子系可以具有
Supported
與更新版本相同的平臺屬性,以縮小支援範圍。 此外,子系可以具有Unsupported
與同一個平臺相同的 屬性,也會縮小父支援範圍。 - 當父系 只列出 [不支援] 清單時,子成員屬性可以新增對新平臺的支援,因為這樣會縮小父支援範圍。 但是它不能有
Supported
與父系相同的平臺屬性,因為這可擴充父代支援。 相同的平臺支援只能新增至套用原始Unsupported
屬性的父系。
- 當父系 僅支援 清單時,子成員屬性就無法加入新的平臺支援,因為這樣會擴充父支援。 新平臺的支援只能新增至父代本身。 但子系可以具有
- 如果
[SupportedOSPlatform("platformVersion")]
針對具有相同platform
名稱的 API 套用一次以上,分析器只會考慮最低版本的 API。 - 如果
[UnsupportedOSPlatform("platformVersion")]
針對具有相同platform
名稱的 API 套用兩次以上,分析器只會考慮具有最早版本的兩個。
注意
一開始支援但不支援的 API (在更新版本中移除) ,預期甚至更新版本中都無法重新支援。
- 最上層
屬性的運作方式和其產生的診斷範例
// 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();
}
處理回報的警告
處理這些診斷的建議方法是確定您在適當的平臺上執行時,只會呼叫平臺特定 API。 以下是可用來解決警告的選項;選擇最適合您情況的時機:
保護呼叫。 您可以在執行時間有條件地呼叫程式碼來達成此目的。 使用其中一個平臺檢查方法,檢查您是否在所需的
Platform
上執行,例如OperatingSystem.Is<Platform>()
或OperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
。 範例。將通話網站標示為平臺特定。 您也可以選擇將自己的 API 標示為平臺特定,因此有效地將需求轉送到您的呼叫端。 使用與參考平臺相依呼叫相同的屬性,標記包含的方法或型別或整個元件。 範例。
使用平臺檢查判斷提示通話網站。 如果您不想要執行時間額外
if
語句的額外負荷,請使用 Debug.Assert(Boolean) 。 範例。刪除程式碼。 通常不是您想要的專案,因為它表示當您Windows使用者使用程式碼時,會失去逼真度。 對於跨平臺替代專案存在的情況,您可能最好透過平臺特定 API 使用該替代專案。
隱藏警告。 您也可以透過 EditorConfig 專案或
#pragma warning disable CA1416
,直接隱藏警告。 不過,使用平臺特定 API 時,這個選項應該是最後一個方法。提示
使用
#pragma
編譯器前置指示詞停用警告時,您鎖定的識別碼會區分大小寫。 例如,ca1416
不會實際停用警告 CA1416。
使用防護方法保護平臺特定 API
guard 方法的平臺名稱應該與呼叫平臺相依的 API 平臺名稱相符。 如果呼叫 API 的平臺字串包含版本:
[SupportedOSPlatform("platformVersion")]
針對 屬性,guard 方法平臺version
應該大於或等於呼叫平臺的Version
。[UnsupportedOSPlatform("platformVersion")]
針對 屬性,guard 方法version
的平臺應該小於或等於呼叫平臺的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 } }
如果您需要保護目標
netstandard
或無法使用新 OperatingSystem API 的程式碼, RuntimeInformation.IsOSPlatform 則可以使用 API,並受netcoreapp
分析器遵守。 但不像 中 OperatingSystem 新增的新 API 一樣優化。 如果結構中不支援 OSPlatform 平臺,您可以呼叫 OSPlatform.Create(String) 並傳入分析器也遵守的平臺名稱。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,並將其作為自訂防護
如先前所示,分析器會辨識 型別中的 OperatingSystem 平臺防護靜態方法,例如 OperatingSystem.IsWindows
和 RuntimeInformation.IsOSPlatform 。 不過,您可能想要快取欄位中的防護結果並重複使用它,或使用自訂防護方法來檢查平臺。 分析器需要將這類 API 辨識為自訂防護,而且不應該針對受其防護的 API 發出警告。 .NET 6 中引進了防護屬性以支援此案例:
SupportedOSPlatformGuardAttribute
批註 API,可做為批註之 API 的 SupportedOSPlatformAttribute 防護。UnsupportedOSPlatformGuardAttribute
批註 API,可做為批註之 API 的 UnsupportedOSPlatformAttribute 防護。
這些屬性可以選擇性地包含版本號碼。 它們可以多次套用來保護多個平臺,並可用來標注欄位、屬性或方法。
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
}
}
}
將通話網站標示為平臺特定
平臺名稱應符合呼叫平臺相依 API。 如果平臺字串包含版本:
[SupportedOSPlatform("platformVersion")]
針對 屬性,呼叫月臺平臺version
應大於或等於呼叫平臺的Version
[UnsupportedOSPlatform("platformVersion")]
針對 屬性,呼叫月臺平臺version
應小於或等於呼叫平臺的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(); }
使用平臺檢查判斷提示呼叫網站
平臺防護範例中使用的所有條件式檢查也可以做為 的條件 Debug.Assert(Boolean) 。
// An API supported only on Linux.
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }
public void Caller()
{
Debug.Assert(OperatingSystem.IsLinux());
LinuxOnlyApi(); // will not warn
}