Platform uyumluluk çözümleyicisi

Büyük olasılıkla "One .NET" sloganını duymuşsunuzdur: herhangi bir uygulama türünü oluşturmaya yönelik tek, birleşik bir platform. .NET 5 SDK'sı ASP.NET Core, Entity Framework Core, WinForms, WPF, Xamarin ve ML.NET içerir ve zaman içinde daha fazla platform için destek ekler. .NET 5, .NET'in farklı türleri hakkında düşünmeniz gerekmeyen, ancak temel işletim sistemini (OS) tamamen soyutlamamaya çalışan bir deneyim sağlamaya çalışır. IOS ve Android için P/Invokes, WinRT veya Xamarin bağlamaları gibi platforma özgü API'leri çağırmaya devam edebilirsiniz.

Ancak bir bileşende platforma özgü API'lerin kullanılması, kodun artık tüm platformlarda çalışmaması anlamına gelir. Geliştiricilerin platforma özgü API'leri istemeden kullandıklarında tanılamalar alması için tasarım zamanında bunu algılamanın bir yoluna ihtiyacımız vardı. Bu hedefe ulaşmak için .NET 5, geliştiricilerin platforma özgü API'leri uygun yerlerde tanımlamasına ve kullanmasına yardımcı olmak için platform uyumluluk çözümleyicisini ve tamamlayıcı API'leri tanıtır.

Yeni API'ler şunlardır:

  • SupportedOSPlatformAttribute API'lere platforma özgü olarak açıklama eklemek ve UnsupportedOSPlatformAttribute API'lere belirli bir işletim sisteminde desteklenmeyen olarak açıklama eklemek. Bu öznitelikler isteğe bağlı olarak sürüm numarasını içerebilir ve çekirdek .NET kitaplıklarındaki platforma özgü bazı API'lere zaten uygulanmış olabilir.
  • Is<Platform>() ve Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) platforma System.OperatingSystem özgü API'leri güvenli bir şekilde çağırmak için sınıfında statik yöntemler. Örneğin, OperatingSystem.IsWindows() Windows'a özgü bir API'ye yapılan bir çağrıyı korumak için kullanılabilir ve OperatingSystem.IsWindowsVersionAtLeast() sürümüne sahip bir Windows'a özgü API çağrısını korumak için kullanılabilir. Bu yöntemlerin platforma özgü API başvurularının koruyucuları olarak nasıl kullanılabileceğini gösteren bu örneklere bakın.

Önkoşullar

Platform uyumluluk çözümleyicisi, Roslyn kod kalitesi çözümleyicilerinden biridir. .NET 5'den başlayarak, bu çözümleyiciler .NET SDK'sı ile birlikte sunulur. Platform uyumluluk çözümleyicisi varsayılan olarak yalnızca veya sonraki bir sürümü hedefleyen net5.0 projeler için etkinleştirilir. Ancak, diğer çerçeveleri hedefleyen projeler için etkinleştirebilirsiniz.

Çözümleyici platform bağımlılığını nasıl belirler?

  • Dağıtılmamış bir API'nin tüm işletim sistemi platformlarında çalıştığı kabul edilir.

  • ile [SupportedOSPlatform("platform")] işaretlenmiş bir API yalnızca belirtilen platforma ve alt kümesi olduğu tüm platformlara taşınabilir olarak kabul edilir.

    • Özniteliği, örneğin [SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")]birden çok platform desteğini belirtmek için birden çok kez uygulanabilir.
    • Platform başka bir platformun alt kümesiyse, özniteliği üst küme platformunun da desteklendiğini gösterir. Örneğin, [SupportedOSPlatform("iOS")] API'nin üzerinde iOS ve üst küme platformunda MacCatalystda desteklendiğini gösterir.
    • Çözümleyici, platforma özgü API'lere uygun bir platform bağlamı olmadan başvurulursa bir uyarı oluşturur:
      • Proje desteklenen platformu (örneğin, iOS'yi hedefleyen bir projeden çağrılan Windows'a özgü bir API) hedeflemiyorsa uyarır<TargetFramework>net5.0-ios14.0</TargetFramework>.
      • Projenin platformlar arası olup olmadığını uyarır ve platforma özgü API'leri (örneğin, platformlar arası TFM'den <TargetFramework>net5.0</TargetFramework>çağrılan Windows'a özgü bir API) çağırır.
      • Belirtilen platformlardan herhangi birini hedefleyen bir projede platforma özgü API'ye başvurulup başvurulmadığını uyarmaz (örneğin, pencereleri <TargetFramework>net5.0-windows</TargetFramework> hedefleyen bir projeden çağrılan Windows'a özgü bir API için ve proje için AssemblyInfo.cs dosya oluşturma etkindir).
      • Platforma özgü API çağrısının ilgili platform denetimi yöntemlerine (örneğin, tarafından OperatingSystem.IsWindows()korunan Windows'a özgü bir API çağrısı) korunuyor olup olmadığı konusunda uyarı vermez.
      • Platforma özgü API'ye aynı platforma özgü bağlamdan başvurulup başvurulmadığını uyarmaz (çağrı sitesi ile de ilişkilendirilir[SupportedOSPlatform("platform")).
  • ile [UnsupportedOSPlatform("platform")] işaretlenmiş bir API, belirtilen platformda ve alt kümesi olduğu ancak diğer tüm platformlar için desteklendiği tüm platformlarda desteklenmeyen bir API olarak kabul edilir.

    • Özniteliği, farklı platformlarla birden çok kez uygulanabilir, örneğin, [UnsupportedOSPlatform("iOS"), UnsupportedOSPlatform("Android29.0")].
    • Platform başka bir platformun alt kümesiyse, özniteliği üst küme platformunun da desteklenmediğini gösterir. Örneğin, [UnsupportedOSPlatform("iOS")] API'nin üzerinde ve üst küme platformunda iOSMacCatalystdesteklenmediğini gösterir.
    • Çözümleyici yalnızca çağrı sitesi için geçerliyse platform bir uyarı üretir:
      • Projenin desteklenmeyen olarak özniteliklendirilen platformu hedefleyip hedeflemediği konusunda uyarır (örneğin, API ile [UnsupportedOSPlatform("windows")] ilişkilendirildiyse ve çağrı sitesi hedefleniyorsa<TargetFramework>net5.0-windows</TargetFramework>).

      • Projenin birden çok hedefli olup olmadığını ve platform varsayılan MSBuild<SupportedPlatform>öğeleri grubuna eklenip eklenmediğini veya platform SupportedPlatform> öğeleri grubuna el ile eklenip eklenmediğini MSBuild<uyarır:

        <ItemGroup>
            <SupportedPlatform Include="platform" />
        </ItemGroup>
        
      • Desteklenmeyen platformu hedeflemeyen veya çok hedefli bir uygulama oluşturup oluşturmadığınız ve platformun varsayılan MSBuild<SupportedPlatform>öğeleri grubuna dahil edilmediği konusunda uyarı vermez.

  • Her iki öznitelik de platform adının bir parçası olarak sürüm numaralarıyla veya sürüm numaraları olmadan örneklenebilir. Sürüm numaraları biçimindedir major.minor[.build[.revision]]; major.minor gereklidir ve build bölümleri revision isteğe bağlıdır. Örneğin, "Windows6.1", Windows sürüm 6.1'i gösterir, ancak "Windows" Windows 0.0 olarak yorumlanır.

Daha fazla bilgi için özniteliklerin nasıl çalıştığına ve hangi tanılamalara neden olduklarına ilişkin örneklere bakın.

Çözümleyici TFM hedef platformlarını nasıl tanır?

Çözümleyici, veya <TargetFrameworks>gibi <TargetFramework> MSBuild özelliklerinden hedef çerçeve adı (TFM) hedef platformlarını denetlemez. TFM'nin bir hedef platformu varsa, MSBuild çözümleyici tarafından kullanılan AssemblyInfo.cs dosyasına hedeflenen platform adıyla bir SupportedOSPlatform öznitelik ekler. Örneğin, TFM isenet5.0-windows10.0.19041, MSBuild özniteliğini AssemblyInfo.cs dosyasına ekler [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")] ve derlemenin tamamı yalnızca Windows olarak kabul edilir. Bu nedenle, 7.0 veya altı sürüme sahip Yalnızca Windows API'lerinin çağrılması projede herhangi bir uyarıya neden olmaz.

Not

proje için AssemblyInfo.cs dosya oluşturma devre dışı bırakılırsa (yani, <GenerateAssemblyInfo> özelliği olarak falseayarlanır), gerekli derleme düzeyi SupportedOSPlatform özniteliği MSBuild tarafından eklenemez. Bu durumda, platformu hedefleseniz bile platforma özgü API kullanımıyla ilgili uyarılar görebilirsiniz. Uyarıları çözmek için AssemblyInfo.cs dosya oluşturmayı etkinleştirin veya özniteliğini projenize el ile ekleyin.

Platform ekleme

.NET 6, bir platformun başka bir platformun alt kümesi olabileceği platform ekleme kavramını tanıtır. Alt küme platformu için ek açıklama, üst küme platformu için aynı desteği (veya eksikliği) ifade eder. Türdeki bir platform denetim yönteminin OperatingSystem özniteliği SupportedOSPlatformGuard("supersetPlatform")] varsa, supersetPlatform yöntemin denetlediği işletim sistemi platformunun üst kümesi olarak kabul edilir.

Örneğin, OperatingSystem.IsIOS() yöntemine atfedilir [SupportedOSPlatformGuard("MacCatalyst")]. Bu nedenle, aşağıdaki deyimler geçerlidir:

  • OperatingSystem.IsIOS() ve OperatingSystem.IsIOSVersionAtLeast yöntemleri yalnızca iOS platformu değil platformu da MacCatalyst denetler.
  • [SupportedOSPlatform("iOS")] API'nin hem üzerinde iOS hem de üst küme platformunda MacCatalystdesteklendiğini gösterir. Bu zımni desteği dışlamak için özniteliğini [UnsupportedOSPlatform("MacCatalyst")] kullanabilirsiniz.
  • [UnsupportedOSPlatform("iOS"), VE MacCatalystüzerinde iOS API'nin desteklenmediğini gösterir. Bu zımni destek eksikliğini [SupportedOSPlatform("MacCatalyst")] dışlamak için özniteliğini kullanabilirsiniz.

Platformun desteklendiğini ve ❌ platformun desteklenmediğini gösterdiği aşağıdaki kapsam matrisini ✔️ göz önünde bulundurun.

Platform SupportedOSPlatform(subset) SupportedOSPlatform(superset) UnsupportedOSPlatform(subset) UnsupportedOSPlatform(superset)
Alt küme -sini ✔️ ✔️
Üst ✔️ ✔️ ✔️ ✔️

İpucu

ve öznitelikleri için SupportedOSPlatformGuardUnsupportedOSPlatformGuard aynı kurallar geçerlidir.

Aşağıdaki kod parçacığı, doğru destek düzeyini ayarlamak için öznitelikleri nasıl birleştirebileceğinizi gösterir.

  // 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() { }

Öznitelik birleşimleri için gelişmiş senaryolar

  • ve [UnsupportedOSPlatform] özniteliklerinin [SupportedOSPlatform] bir bileşimi varsa, tüm öznitelikler işletim sistemi platformu tanımlayıcısı tarafından gruplandırılır:

    • Yalnızca desteklenenler listesi. Her işletim sistemi platformu için en düşük sürüm bir [SupportedOSPlatform] öznitelikse, API'nin yalnızca listelenen platformlar tarafından desteklendiği ve diğer tüm platformlar tarafından desteklenmediği kabul edilir. Her platform için isteğe bağlı [UnsupportedOSPlatform] öznitelikler, api'nin belirtilen sürümden başlayarak kaldırıldığını belirten desteklenen en düşük sürümün yalnızca daha yüksek bir sürümüne sahip olabilir.

      // 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();
      
    • Yalnızca desteklenmeyenler listesi. Her işletim sistemi platformu için en düşük sürüm bir [UnsupportedOSPlatform] öznitelikse, API'nin yalnızca listelenen platformlar tarafından desteklenmediği ve diğer tüm platformlar tarafından desteklendiği kabul edilir. Listede aynı platforma sahip ancak daha yüksek bir sürüme sahip [SupportedOSPlatform] olan ve API'nin bu sürümden başlayarak desteklendiğini belirten bir öznitelik olabilir.

      // 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();
      
    • Tutarsız liste. Bazı platformlar için en düşük sürüm diğer platformlar [SupportedOSPlatform] içinse [UnsupportedOSPlatform] , çözümleyici için desteklenmeyen tutarsız olarak kabul edilir. Tutarsızlık oluşursa çözümleyici platformları [UnsupportedOSPlatform] yoksayar.

      • ve [UnsupportedOSPlatform] özniteliklerinin [SupportedOSPlatform] en düşük sürümleri eşitse çözümleyici platformu Yalnızca desteklenenler listesinin bir parçası olarak kabul eder.
  • Platform öznitelikleri türler, üyeler (yöntemler, alanlar, özellikler ve olaylar) ve farklı platform adlarına veya sürümlerine sahip derlemelere uygulanabilir.

    • En üst düzeyde target uygulanan öznitelikler, tüm üyelerini ve türlerini etkiler.
    • Alt düzey öznitelikler yalnızca "alt ek açıklamalar platform desteğini daraltabilir, ancak genişletemez" kuralına bağlı kalırsa geçerlidir.
      • Üst öğe yalnızca desteklenenler listesine sahip olduğunda, alt üye öznitelikleri yeni bir platform desteği ekleyemez, bu da üst desteği genişletiyor olabilir. Yeni platform desteği yalnızca üst öğeye eklenebilir. Ancak alt öğe, desteği daraltan sonraki sürümlerle aynı platform için özniteliğine sahip Supported olabilir. Ayrıca alt öğe, üst desteği de daraltan aynı platforma sahip özniteliğine sahip Unsupported olabilir.
      • Üst öğe yalnızca desteklenmeyenler listesine sahip olduğunda, alt üye öznitelikleri yeni bir platform için destek ekleyebilir, bu da üst desteği daraltabilir. Ancak üst destek genişletildiği için üst ile aynı platform için özniteliğine sahip Supported olamaz. Aynı platform için destek yalnızca özgün Unsupported özniteliğin uygulandığı üst öğeye eklenebilir.
    • Aynı platform ada sahip bir API için birden çok kez uygulanırsa [SupportedOSPlatform("platformVersion")] çözümleyici yalnızca en düşük sürüme sahip olanı dikkate alır.
    • Aynı platform ada sahip bir API için ikiden fazla uygulanırsa [UnsupportedOSPlatform("platformVersion")] çözümleyici yalnızca en eski sürümlere sahip ikisini dikkate alır.

    Not

    Başlangıçta desteklenen ancak daha sonraki bir sürümde desteklenmeyen (kaldırılan) bir API'nin daha sonraki bir sürümde yeniden desteklenmesi beklenmemektedir.

Özniteliklerin nasıl çalıştığını ve hangi tanılamaları ürettiklerini gösteren örnekler

// 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();
}

Bildirilen uyarıları işleme

Bu tanılamalarla başa çıkmanın önerilen yolu, uygun bir platformda çalışırken yalnızca platforma özgü API'leri çağırdığınızdan emin olmaktır. Uyarıları ele almak için kullanabileceğiniz seçenekler aşağıdadır; durumunuz için en uygun olanı seçin:

  • Aramayı koru. Bunu yapmak için çalışma zamanında kodu koşullu olarak çağırabilirsiniz. Platform denetimi yöntemlerinden birini (örneğin, OperatingSystem.Is<Platform>() veyaOperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)) kullanarak istediğiniz Platform bir üzerinde çalışıp çalışmadığınızı denetleyin. Örnek.

  • Arama sitesini platforma özgü olarak işaretleyin. Ayrıca kendi API'lerinizi platforma özgü olarak işaretlemeyi de seçebilirsiniz; bu nedenle gereksinimleri yalnızca arayanlarınıza iletmeniz gerekir. İçerilen yöntemi veya türü veya derlemenin tamamını başvuruda bulunılan platforma bağımlı çağrıyla aynı özniteliklerle işaretleyin. Örnekler.

  • Platform denetimiyle çağrı sitesini onaylar. Çalışma zamanında ek if bir deyimin ek yükünü istemiyorsanız kullanın Debug.Assert(Boolean). Örnek.

  • Kodu silin. Genellikle istediğiniz gibi değildir çünkü kodunuz Windows kullanıcıları tarafından kullanıldığında aslına uygunluğu kaybedersiniz. Platformlar arası alternatifin mevcut olduğu durumlarda, platforma özgü API'ler üzerinden bu seçeneği kullanmanız daha iyi olabilir.

  • Uyarıyı gizleme. Ayrıca bir EditorConfig girdisi veya aracılığıyla uyarıyı gizlemeniz yeterlidir#pragma warning disable CA1416. Ancak, platforma özgü API'ler kullanılırken bu seçenek son çare olmalıdır.

    İpucu

    Derleyici öncesi yönergelerini kullanarak #pragma uyarıları devre dışı bırakırken, hedeflediğiniz tanımlayıcılar büyük/küçük harfe duyarlıdır. Örneğin, ca1416 ca1416 uyarısını devre dışı bırakmaz.

Koruma yöntemleriyle platforma özgü API'leri koruma

Guard yönteminin platform adı, çağıran platforma bağımlı API platform adıyla eşleşmelidir. Çağrı API'sinin platform dizesi sürümü içeriyorsa:

  • özniteliği için [SupportedOSPlatform("platformVersion")] guard yöntemi platformu, çağıran platformun versionVersiondeğerinden büyük veya buna eşit olmalıdır.

  • özniteliği için [UnsupportedOSPlatform("platformVersion")] , guard yönteminin platformu, çağıran platformun versionVersiondeğerinden küçük veya buna eşit olmalıdır.

    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
        }
    }
    
  • Yeni API'leri netstandard hedefleyen veya netcoreappOperatingSystem kullanılamayan kodu korumanız gerekiyorsa API RuntimeInformation.IsOSPlatform kullanılabilir ve çözümleyici tarafından dikkate alınacaktır. Ancak, 'ye eklenen OperatingSystemyeni API'ler kadar iyileştirilmiş değildir. Yapıda OSPlatform platform desteklenmiyorsa çağırabilir ve çözümleyicinin de dikkate aldığı platform adını geçirebilirsiniz 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
        }
    }
    

PLATFORM guard öznitelikleriyle API'lere ek açıklama ekleyin ve özel koruma olarak kullanın

Daha önce gösterildiği gibi çözümleyici, türündeki OperatingSystem platform-guard statik yöntemlerini tanır, örneğin OperatingSystem.IsWindows, ve .RuntimeInformation.IsOSPlatform Ancak, koruma sonucunu bir alanda önbelleğe alıp yeniden kullanmak veya platformu denetlemek için özel koruma yöntemleri kullanmak isteyebilirsiniz. Çözümleyicinin bu tür API'leri özel bir koruma olarak tanıması ve bu API'ler tarafından korunan API'ler için uyarı vermemesi gerekir. Bu senaryoyu desteklemek için .NET 6'da guard öznitelikleri kullanıma sunulmuştur:

  • SupportedOSPlatformGuardAttribute ile ek açıklama ekleyen API'ler için koruma olarak kullanılabilecek API'lere açıklama ekler SupportedOSPlatformAttribute.
  • UnsupportedOSPlatformGuardAttribute ile ek açıklama ekleyen API'ler için koruma olarak kullanılabilecek API'lere açıklama ekler UnsupportedOSPlatformAttribute.

Bu öznitelikler isteğe bağlı olarak bir sürüm numarası içerebilir. Birden fazla platformu korumak için birden çok kez uygulanabilirler ve bir alana, özelliğe veya yönteme açıklama eklemek için kullanılabilirler.

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
        }
    }
}

Çağrı sitesini platforma özgü olarak işaretleme

Platform adları, çağıran platforma bağımlı API ile eşleşmelidir. Platform dizesi bir sürüm içeriyorsa:

  • özniteliği için [SupportedOSPlatform("platformVersion")] , arama sitesi platformu, arama platformununkinden version büyük veya buna eşit olmalıdır Version

  • özniteliği için [UnsupportedOSPlatform("platformVersion")] çağrı sitesi platformu, arama platformunun versionVersion

    // 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();
    }
    

Platform denetimi ile çağrı sitesini onaylama

Platform koruyucusu örneklerinde kullanılan tüm koşullu denetimler için Debug.Assert(Boolean)koşulu olarak da kullanılabilir.

// An API supported only on Linux.
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }

public void Caller()
{
    Debug.Assert(OperatingSystem.IsLinux());

    LinuxOnlyApi(); // will not warn
}

Ayrıca bkz.