您可能已聽到「一個 .NET」的座右銘:建置任何類型的應用程式的單一統一平臺。 .NET SDK 包含 ASP.NET Core、Entity Framework Core、Windows Forms、WPF 和 ML.NET,並會隨著時間新增對更多平台的支援。 .NET 5+ 致力於提供一種體驗,讓您不必思考不同版本的 .NET,但不會嘗試完全抽象基礎操作系統 (OS)。 您可以繼續呼叫平臺特定 API,例如 P/Invokes 和 WinRT。
但是,在元件上使用平臺特定 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 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,則不會發出警告(例如,當專案目標是 Windows 時,呼叫 Windows 特定的 API 且已啟用
<TargetFramework>net5.0-windows</TargetFramework>
檔案生成)。 - 如果平臺特定 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
專案群組中,或<SupportedPlatform>
手動包含在 SupportedPlatform 專案群組中platform
MSBuild
,則會<:<ItemGroup> <SupportedPlatform Include="platform" /> </ItemGroup>
如果您要建置的應用程式不是以不支援的平臺為目標,或是多重目標,且平臺未包含在預設 專案群組中,則不會
<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 會在 AssemblyInfo.cs 文件中插入帶有目標平台名稱的SupportedOSPlatform
屬性,供分析器使用。 例如,如果 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
作為方法所檢查之操作系統平臺的超集。
例如,方法OperatingSystem.IsIOS()被歸因為[SupportedOSPlatformGuard("MacCatalyst")]
。 因此,適用下列語句:
-
OperatingSystem.IsIOS()和OperatingSystem.IsIOSVersionAtLeast方法不僅會檢查
iOS
平臺,也會檢查MacCatalyst
平臺。 -
[SupportedOSPlatform("iOS")]
表示該 API 不僅在iOS
上支援,也在其超集平台MacCatalyst
上支援。 您可以使用[UnsupportedOSPlatform("MacCatalyst")]
屬性來排除此隱含支援。 -
[UnsupportedOSPlatform("iOS")
表示在iOS
和MacCatalyst
上不支援 API。 您可以使用[SupportedOSPlatform("MacCatalyst")]
屬性來排除此隱含缺乏支援。
請考慮下列涵蓋範圍矩陣,其中 ✔️ 表示支持平臺,並 ❌ 表示 不支持 平臺。
平台 | SupportedOSPlatform(subset) |
SupportedOSPlatform(superset) |
UnsupportedOSPlatform(subset) |
UnsupportedOSPlatform(superset) |
---|---|---|---|---|
子集 | ✔️ | ❌ | ✔️ | ❌ |
超集 | ✔️ | ✔️ | ✔️ | ✔️ |
小提示
相同的規則適用於 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() { }
屬性組合的進階案例
如果同時存在
[SupportedOSPlatform]
和[UnsupportedOSPlatform]
屬性的組合,所有屬性都會依據作業系統平台識別碼進行分組。支援的清單只有這些。 如果每個 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]
平臺。- 如果
[SupportedOSPlatform]
和[UnsupportedOSPlatform]
屬性的最低版本相等,分析器會將平台視為 僅支援清單 的一部分。
- 如果
平台屬性可以套用至具有不同平臺名稱或版本的類型、成員(方法、欄位、屬性和事件)和元件。
- 最上層
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")]
屬性方面,監控方法的平台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
或netcoreapp
,而無法使用新的OperatingSystem API 的程式碼,則可以使用RuntimeInformation.IsOSPlatform API,並會被分析器遵守。 但不像 中 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 保護的 API 發出警告。 .NET 6 中引進了防護屬性,以支援此案例:
-
SupportedOSPlatformGuardAttribute
標註的 API 可用來作為為 SupportedOSPlatformAttribute 標註 API 的保護措施。 -
UnsupportedOSPlatformGuardAttribute
標註的 API 可用來作為為 UnsupportedOSPlatformAttribute 標註 API 的保護措施。
這些屬性可以選擇性地包含版本號碼。 它們可以套用多次來保護多個平臺,並可用於標註字段、屬性或方法。
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
}