Platform uyumluluk çözümleyicisi

Büyük olasılıkla "One .NET" (Herhangi bir uygulama türüne sahip olmak için tek ve birleşik bir platform) ifadesini duymuşdur. .NET 5 SDK'sı ASP.NET Core, Entity Framework Core, WinForms, WPF, Xamarin ve ML.NET'i içerir ve zaman içinde daha fazla platform için destek ekler. .NET 5, .NET'in farklı çeşitlerini gerekçeli olarak ifade etmek zorunda olmadığınız ancak temel işletim sistemini (OS) tamamen soyutlama girişimine gerek olmayan bir deneyim sunmak için çabalar. iOS ve Android için P/Invokes, WinRT veya Xamarin bağlamaları gibi platforma özgü API'leri çağırmaya devam edersiniz.

Ancak bir bileşende platforma özgü API'ler kullanmak, kodun artık tüm platformlarda çalışmay anlamına gelir. Geliştiricilerin yanlışlıkla platforma özgü API'leri kullanarak tanılama elde etmek için tasarım zamanında bunu algılamak için bir yol gerekiyordu. Bu hedefe ulaşmak için .NET 5, geliştiricilerin uygun olduğunda platforma özgü API'leri tanımlamalarına ve kullanmalarına yardımcı olmak için platform uyumluluk çözümleyicisi ve tamamlayıcı API'leri sunar.

Yeni API'ler şunlardır:

  • SupportedOSPlatformAttribute API'lere platforma özgü olarak açıklama yapmak ve API'lere belirli bir işletim sistemi üzerinde desteklenmeyenler UnsupportedOSPlatformAttribute olarak açıklama yapmak için. Bu öznitelikler isteğe bağlı olarak sürüm numarasını içerebilir ve temel .NET kitaplıklarında platforma özgü bazı API'lere zaten uygulanmıştır.
  • Is<Platform>() ve Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) platforma özgü System.OperatingSystem API'leri güvenli bir şekilde çağırmaya yönelik sınıfındaki statik yöntemler. Örneğin, belirli bir API'ye yönelik çağrıyı Windows için, () ise sürüme özgü api çağrısını OperatingSystem.IsWindows() OperatingSystem.IsWindowsVersionAtLeast Windows () kullanılabilir. Bu yöntemlerin platforma özgü API başvurularının korumaları olarak nasıl kullanılay örneklere bakın.

Önkoşullar

Platform uyumluluğu çözümleyicisi, Roslyn kod kalitesi çözümleyicilerinden biri. .NET 5'te başlayarak, bu çözümleyiciler .NET SDK'sı ile birlikte gelir. Platform uyumluluğu çözümleyicisi varsayılan olarak yalnızca hedef veya sonraki bir sürümü net5.0 hedef alan projeler için etkindir. Ancak, bunu diğer çerçeveleri hedef alan projeler için etkinleştirsiniz.

Çözümleyicinin platform bağımlılığını belirlemesi

  • Tüm işletim sistemi platformlarında çalışmak için atfedlanmamış bir API'nin olduğu düşünülmektedir.

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

    • özniteliği birden çok platform desteğini belirtmek için birden çok kez uygulanabilir, örneğin [SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")] .
    • Platform başka bir platformun bir alt kümesiise, özniteliği üst küme platformunun da desteklenemektedir. Örneğin, API'nin üzerinde ve ayrıca üst küme [SupportedOSPlatform("iOS")] iOS platformunda desteklenecek anlamına MacCatalyst gelir.
    • Çözümleyici, platforma özgü API'lere uygun bir platform bağlamı olmadan başvurulsa bir uyarı üretir:
      • Proje desteklenen platformu hedeflemezse (örneğin, iOS'u Windows bir projeden çağrılır) uyarı <TargetFramework>net5.0-ios14.0</TargetFramework> alır.
      • Proje platformlar arası ise ve platforma özgü API'ler (örneğin, platformlar arası TFM'den çağrılır Windows api'ler) çağırıyorsa uyar. <TargetFramework>net5.0</TargetFramework>
      • Belirtilen platformlardan herhangi birini hedef alan bir proje içinde platforma özgü API'ye başvurulsa (örneğin, proje hedefleme pencerelerinden çağrılan Windows'ye özgü bir API için ve proje için <TargetFramework>net5.0-windows</TargetFramework> AssemblyInfo.cs dosyası oluşturma etkinleştirildiğinde) uyarmaz.
      • Platforma özgü API çağrısı karşılık gelen platform denetimi yöntemleriyle korunuyorsa (örneğin, tarafından Windows API çağrısı) uyarmaz. OperatingSystem.IsWindows()
      • Platforma özgü API'ye aynı platforma özgü bağlamdan başvurulsa (ile de öznitelikli çağrı sitesi) uyarmaz. [SupportedOSPlatform("platform")
  • ile işaretlenen API'nin belirtilen platformda ve alt kümesi olduğu tüm platformlarda desteklenmemektedir ancak diğer tüm [UnsupportedOSPlatform("platform")] platformlar için de desteklenmemektedir.

    • özniteliği, gibi farklı platformlarla birden çok kez [UnsupportedOSPlatform("iOS"), UnsupportedOSPlatform("Android29.0")] uygulanabilir.
    • Platform başka bir platformun alt kümesi ise,özniteliği üst küme platformunun da desteklenmemektedir. Örneğin, [UnsupportedOSPlatform("iOS")] API'nin ve ayrıca üst küme iOS platformunda desteklenmemektedir. MacCatalyst
    • Çözümleyici yalnızca çağrısı sitesi için geçerli ise bir uyarı platform üretir:
      • Projenin desteklenmeyen olarak öznitelikli platformu hedeflemesi (örneğin, API ile öznitelikli ise ve çağrı sitesi hedef alıyorsa) [UnsupportedOSPlatform("windows")] uyar. <TargetFramework>net5.0-windows</TargetFramework>

      • Proje çok hedefli ise ve varsayılan öğe grubuna dahil platform edilirse <SupportedPlatform> MSBuild veya öğeleri öğeleri grubuna el ile dahil platform MSBuild <SupportedPlatform> edilirse uyar:

        <ItemGroup>
            <SupportedPlatform Include="platform" />
        </ItemGroup>
        
      • Desteklenmeyen platformu hedeflememiş veya çoklu hedefli bir uygulama ıyorsanız ve platform <SupportedPlatform> varsayılan uygulama öğeleri grubuna dahil MSBuild uyarmaz.

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

Daha fazla bilgi için özniteliklerin çalışma örneklerine ve neden olduğu tanılamalara bakın.

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

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

Not

Proje için AssemblyInfo.cs dosya oluşturma devre dışı bırakılırsa (yani özelliği olarak ayarlanırsa), gerekli derleme düzeyi özniteliği, <GenerateAssemblyInfo> false SupportedOSPlatform MSBuild. Bu durumda, platformu hedefleseniz bile platforma özgü API kullanımına yönelik uyarılar görebilirsiniz. Uyarıları çözmek için AssemblyInfo.cs dosya oluşturma özelliğini etkinleştirin veya özniteliği projenize el ile ekleyin.

Platform ekleme

.NET 6, bir platformun başka bir platformun alt kümesi olduğu platform ekleme kavramını sunar. Alt küme platformu için ek açıklama, üst küme platformu için aynı desteği (veya eksiklik) ifade eder. Türe sahip bir platform denetimi yöntemi özniteliğine sahipse, yöntemin kontrol etmek için OperatingSystem SupportedOSPlatformGuard("supersetPlatform")] bir işletim sistemi supersetPlatform platformunun üst kümesi olarak kabul edilir.

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

  • ve OperatingSystem.IsIOS() OperatingSystem.IsIOSVersionAtLeast yöntemleri yalnızca platformu iOS değil, platformu da MacCatalyst kontrol ediyor.
  • [SupportedOSPlatform("iOS")], API'nin üzerinde ve ayrıca üst iOS küme platformunda desteklemektedir. MacCatalyst Bu örtük desteği [UnsupportedOSPlatform("MacCatalyst")] dışlamak için özniteliğini kullanabilirsiniz.
  • [UnsupportedOSPlatform("iOS") , ve üzerinde API'nin destekçi olmadığını iOS MacCatalyst gösterir. Bu örtük destek [SupportedOSPlatform("MacCatalyst")] eksikliğini dışlamak için özniteliğini kullanabilirsiniz.

Aşağıdaki kapsam matrisini göz önünde ✔️ platform desteklemektedir ve ❌ platformun destek olmadığını gösterir.

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

İpucu

Aynı kurallar ve öznitelikleri SupportedOSPlatformGuard için UnsupportedOSPlatformGuard de geçerlidir.

Aşağıdaki kod parçacığında, doğru destek düzeyini ayarlamak için öznitelikleri nasıl birleştirebilirsiniz?

  // 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 özniteliklerinin [SupportedOSPlatform] [UnsupportedOSPlatform] bir birleşimi varsa, tüm öznitelikler işletim sistemi platformu tanımlayıcısına göre gruplandı:

    • Yalnızca listesini destekler. Her işletim sistemi platformu için en düşük sürüm bir öznitelikse, API yalnızca listelenen platformlar tarafından desteklenmiş ve diğer tüm platformlar [SupportedOSPlatform] tarafından desteklenmemektedir. Her platform için isteğe bağlı öznitelikler desteklenen en düşük sürümün yalnızca daha yüksek bir sürümüne sahip olabilir ve bu da API'nin belirtilen sürümden başlayarak [UnsupportedOSPlatform] kaldırıldığına dikkati gösterir.

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

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

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

    • En üst düzeyde uygulanan öznitelikler target tüm üyelerini ve türlerini etkiler.
    • Alt düzey öznitelikler yalnızca "alt ek açıklamalar platform desteğini daraltabiliyor, ancak genişlete açamaz" kuralına bağlı kalmaları için geçerlidir.
      • Üst öğenin yalnızca desteklenenler listesi olduğunda, alt üye öznitelikleri üst desteği genişleterek yeni bir platform desteği ek olamaz. Yeni platform desteği yalnızca üst platforma eklenebilir. Ancak alt, desteği Supported daraltan sonraki sürümlerle aynı platform için özniteliğine sahip olabilir. Ayrıca alt öğe, üst desteği Unsupported de daraltan aynı platforma sahip özniteliğine sahip olabilir.
      • Üst öğenin yalnızca desteklenmeyen listesi olduğunda, alt üye öznitelikleri üst desteği daraltan yeni bir platform için destek ekleyebilir. Ancak üst desteği genişleten üst platform için özniteliği Supported olamaz. Aynı platform için destek yalnızca özgün özniteliğin uygulandığı üst Unsupported öğeye eklenebilir.
    • Aynı adı kullanan bir API için birden çok kez uygulanırsa [SupportedOSPlatform("platformVersion")] platform çözümleyici yalnızca en düşük sürüme sahip olanı dikkate almaktadır.
    • Aynı adla bir API için ikiden fazla uygulanırsa çözümleyici yalnızca en eski [UnsupportedOSPlatform("platformVersion")] platform sürümlere sahip olan iki sürümü dikkate almaktadır.

    Not

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

Özniteliklerin nasıl iş yaptığını ve hangi tanılamaları ürettiğini ö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 ApiSupportedFromWindows8UnsupportFromWindows10() { }

// 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. 'ApiSupportedFromWindows8UnsupportFromWindows10()' is only supported on: 'windows' from version 6.2 to 10.0.19041.0
    ApiSupportedFromWindows8UnsupportFromWindows10();

    // 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ş etmek için önerilen yol, uygun bir platformda çalıştırıldıklarda yalnızca platforma özgü API'leri çağırma emin olmaktır. Uyarılara adres olarak kullanabileceğiniz seçenekler şunlardır: durumunuz için en uygun seçeneği seçin:

  • çağrısını koruma. Kodu çalışma zamanında koşullu olarak çağırarak bunu başarabilirsiniz. Platform denetimi yöntemlerinden birini kullanarak veya gibi bir istenen üzerinde çalıştırıp Platform çalışmamayabilirsiniz. OperatingSystem.Is<Platform>() OperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) Örnek .

  • Çağrı sitesini platforma özgü olarak işaretleme. Ayrıca kendi API'lerinizi platforma özgü olarak işaretlemeyi de seçebilirsiniz, böylece gereksinimleri çağıranlara etkili bir şekilde iletebilirsiniz. Içeren yöntemi veya türü ya da tüm derlemeyi, başvurulan platforma bağımlı çağrıyla aynı özniteliklerle işaretle. Örnekler.

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

  • kodunu silin. Genellikle istediğiniz şey değildir çünkü kodunuz kullanıcılar tarafından kullanılırken doğruluk Windows olur. Platformlar arası alternatifin mevcut olduğu durumlarda, bunu platforma özgü API'ler üzerinden kullanmak daha iyi olur.

  • uyarısını bastır. Uyarıyı bir EditorConfig girdisi veya aracılığıyla da gizlemeyi de sebilirsiniz. #pragma warning disable CA1416 Ancak, platforma özgü API'ler kullanırken bu seçenek son seçenektir.

    İpucu

    Ön derleyici yönergelerini kullanarak uyarıları devre dışı bırakarak, hedeflemekte olduğunu #pragma tanımlayıcılar büyük/büyük/büyük harfe duyarlıdır. Örneğin, ca1416 ca1416 uyarısını devre dışı bırakmaz.

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

Koruma yönteminin platform adı, çağıran platforma bağımlı API platform adıyla eşleşmeli. Çağıran API'nin platform dizesinin sürümü varsa:

  • özniteliği [SupportedOSPlatform("platformVersion")] için, koruma yöntemi platformunun version çağıran platformun değerine eşit veya daha büyük olması Version gerekir.

  • özniteliği [UnsupportedOSPlatform("platformVersion")] için, guard yönteminin platformunun çağıran platformun değerine version eşit veya daha küçük olması Version gerekir.

    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)))
        {
            ApiSupportedFromWindows8UnsupportFromWindows10();
        }
    
        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
        }
    }
    
  • Hedefleri veya yeni API'ler kullanılabilir değilken kodu korumaya ihtiyacınız varsa, API kullanılabilir ve çözümleyici netstandard netcoreapp tarafından kabul OperatingSystem RuntimeInformation.IsOSPlatform edilir. Ancak, içinde eklenen yeni API'ler kadar iyileştirilmiş OperatingSystem değildir. Platform yapıda desteklenmiyorsa, çağırarak çözümleyicinin de kabul eden OSPlatform OSPlatform.Create(String) platform adını iletirsiniz.

    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 koruma öznitelikleriyle API'lere açıklama ek açıklama ve özel koruma olarak kullanma

Daha önce gösterildiği gibi çözümleyici, türünde platform koruması statik yöntemlerini tanır, örneğin OperatingSystem OperatingSystem.IsWindows , ve ayrıca RuntimeInformation.IsOSPlatform . Bununla birlikte, bir alanda guard sonucu önbelleğe almak ve yeniden kullanmak ya da bir platformu denetlemeye yönelik özel koruma yöntemlerini kullanmak istiyor olabilir. Çözümleyicinin bu TÜR API'leri özel koruma olarak tanıması ve bu API'ler tarafından koruma altında olan API'ler için uyarmamalıdır. Bu senaryoyu desteklemek için .NET 6'da koruma öznitelikleri tanıtıldı:

  • SupportedOSPlatformGuardAttribute ile açıklama ek açıklamalı API'ler için koruma olarak kullanılan API'lere açıklama ek açıklamalarını SupportedOSPlatformAttribute eder.
  • UnsupportedOSPlatformGuardAttribute ile açıklama ek açıklamalı API'ler için koruma olarak kullanılan API'lere açıklama ek açıklamalarını UnsupportedOSPlatformAttribute eder.

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

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şmeli. Platform dizesi bir sürüme sahipse:

  • özniteliği [SupportedOSPlatform("platformVersion")] için çağrı sitesi version platformunun, çağıran platforma eşit veya daha büyük olması gerekir Version

  • özniteliği [UnsupportedOSPlatform("platformVersion")] için çağrı sitesi platformunun, çağrı platformunun değerine version eşit veya daha küçük olması gerekir 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 ApiSupportedFromWindows8UnsupportFromWindows10() { }
    
    // 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. 'ApiSupportedFromWindows8UnsupportFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later.
        ApiSupportedFromWindows8UnsupportFromWindows10();
    
        // 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. 'ApiSupportedFromWindows8UnsupportFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later.
        ApiSupportedFromWindows8UnsupportFromWindows10();
    
        // 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.
        ApiSupportedFromWindows8UnsupportFromWindows10();
    
        // 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 denetimiyle çağrı sitesini onaylama

Platform koruma örneklerde kullanılan tüm koşullu denetimler koşulu olarak da Debug.Assert(Boolean) 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.