平台相容性分析器

您可能聽過「一個 .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 包括:

必要條件

平臺相容性分析器是其中一個 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")) 來參考,則不會發出警告
  • 標示為 [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 在 和 其超集合平臺上也支援 iOSMacCatalyst 您可以使用 [UnsupportedOSPlatform("MacCatalyst")] 屬性來排除此隱含支援。
  • [UnsupportedOSPlatform("iOS")表示 和 MacCatalyst 不支援 iOS API。 您可以使用 [SupportedOSPlatform("MacCatalyst")] 屬性來排除此隱含缺少支援。

請考慮下列涵蓋範圍矩陣,其中 ✔️ 表示支援平臺,並 ❌ 指出 不支援 平臺。

平台 SupportedOSPlatform(subset) SupportedOSPlatform(superset) UnsupportedOSPlatform(subset) UnsupportedOSPlatform(superset)
Subset ✔️ ✔️
超集合 ✔️ ✔️ ✔️ ✔️

提示

相同的規則適用于 SupportedOSPlatformGuardUnsupportedOSPlatformGuard 屬性。

下列程式碼片段示範如何結合屬性來設定正確的支援層級。

  // 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.IsWindowsRuntimeInformation.IsOSPlatform 。 不過,您可能想要快取欄位中的防護結果並重複使用它,或使用自訂防護方法來檢查平臺。 分析器需要將這類 API 辨識為自訂防護,而且不應該針對受其防護的 API 發出警告。 .NET 6 中引進了防護屬性以支援此案例:

這些屬性可以選擇性地包含版本號碼。 它們可以多次套用來保護多個平臺,並可用來標注欄位、屬性或方法。

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
}

另請參閱