Aracılığıyla paylaş


Platform uyumluluk çözümleyicisi

.NET, her tür uygulamayı oluşturmaya yönelik tek ve birleşik bir platformdur. .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. P/Invokes ve WinRT 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. Platform uyumluluk çözümleyicisi ve tamamlayıcı API'ler, uygun yerlerde platforma özgü API'leri belirlemenize ve kullanmanıza yardımcı olacak tanılamalar sağlar.

Tamamlayıcı 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) sınıfında, platforma özgü API'leri güvenli bir şekilde çağırmak için 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. 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ış birAPI'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 birden [SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")] 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 iOS üzerinde ve aynı zamanda onun üst kümesi olan platform MacCatalystda desteklendiğini belirtir.
    • Çö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.
      • Uyarmaz, eğer belirtilen platformlardan herhangi birini hedefleyen bir projede platforma özgü API'ye başvurulursa (örneğin, Windows'u 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 korunan Windows'a özgü bir API çağrısı) korunuyor olup olmadığı OperatingSystem.IsWindows().
      • Platforma özgü API'ye aynı platforma özgü bağlamdan başvurulduğunda uyarı vermeyen (çağrı sitesi de bu bağlamda etiketlenmişse).
  • 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")] hem iOS API'nin desteklenmediğini hem de üst küme platformu MacCatalyst üzerinde desteklenmediğini gösterir.
    • Çözümleyici yalnızca çağrı sitesi için geçerliyse bir platform ü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>).

      • Uyarır projenin birden çok hedefe yönelik olduğunu ve platform öğesinin varsayılan MSBuild <SupportedPlatform> öğeleri grubuna eklenmiş olup olmadığını veya platform öğesinin MSBuild<SupportedPlatform> öğe grubuna manuel olarak eklenmiş olup olmadığını:

        <ItemGroup>
            <SupportedPlatform Include="platform" />
        </ItemGroup>
        
      • Desteklenmeyen platformu hedeflemeyen veya çok hedefli bir uygulama oluşturup oluşturmadığınız ve platformun varsayılan öğeleri grubuna dahil edilmediği <SupportedPlatform> 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 <TargetFramework>gibi <TargetFrameworks> MSBuild özelliklerinden hedef çerçeve adı (TFM) hedef platformlarını denetlemez. TFM'nin bir hedef platformu varsa MSBuild, SupportedOSPlatform tarafından kullanılan AssemblyInfo.cs dosyasına hedeflenen platform adıyla bir öznitelik ekler. Örneğin, TFM net5.0-windows10.0.19041 ise, MSBuild [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")] özniteliğini AssemblyInfo.cs dosyasına ekler ve böylece tüm derleme sadece Windows ile uyumlu 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.

Uyarı

proje için AssemblyInfo.cs dosya oluşturma devre dışı bırakılırsa (yani, <GenerateAssemblyInfo> özelliği olarak ayarlanır false), 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 katılımı

.NET 6, bir platformun başka bir platformun alt kümesi olabileceği platform ekleme kavramını kullanıma sunulmuştur. 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öntemi [SupportedOSPlatformGuard("MacCatalyst")] olarak atfedilir. Bu nedenle, aşağıdaki deyimler geçerlidir:

  • OperatingSystem.IsIOS() ve OperatingSystem.IsIOSVersionAtLeast yöntemleri yalnızca iOS platformunu değil, aynı zamanda MacCatalyst platformunu da 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"), iOS ve MacCatalyst üzerinde 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.

Platforma SupportedOSPlatform(subset) SupportedOSPlatform(superset) UnsupportedOSPlatform(subset) UnsupportedOSPlatform(superset)
Alt küme ✔️ ✔️
Üst ✔️ ✔️ ✔️ ✔️

Tavsiye

SupportedOSPlatformGuard ve UnsupportedOSPlatformGuard öznitelikleri için 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

  • [SupportedOSPlatform] ve [UnsupportedOSPlatform] özniteliklerinin bir kombinasyonu mevcutsa, tüm öznitelikler işletim sistemi platform 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. Listedeki aynı platforma fakat daha yüksek bir sürüme sahip olan [SupportedOSPlatform] özniteliği, API'nin bu sürümden itibaren desteklendiğini belirtebilir.

      // 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 [SupportedOSPlatform], diğer platformlar içinse [UnsupportedOSPlatform] olduğunda, çözümleyici tarafından desteklenmeyen bir tutarsızlık olarak kabul edilir. Tutarsızlık oluşursa, analizleyici [UnsupportedOSPlatform] platformları görmezden gelir.

      • [SupportedOSPlatform] ve [UnsupportedOSPlatform] özniteliklerinin 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şletemezler" kanununa uygun olması halinde geçerlidir.
      • Üst öge yalnızca desteklenenler listesine sahip olduğunda, alt üye öznitelikleri yeni bir platform desteği ekleyemez, çünkü bu üst destek kapsamını genişletmiş olur. Yeni bir platformun desteği yalnızca ana öğeye eklenebilir. Ancak çocuk, sonraki sürümlerde desteği daraltan aynı platform için Supported özniteliğine sahip olabilir. Ayrıca, çocuk, ebeveyn desteğini daraltan aynı platforma sahip Unsupported özniteliğine sahip olabilir.
      • Üst öğe yalnızca desteklenmeyenler listesine sahip olduğunda, alt üye öznitelikleri yeni bir platform için destek sağlayabilir, bu da üst öğenin desteğini daraltabilir. Ancak bu, üst desteği genişlettiği için üst ile aynı platform için Supported özniteliğine sahip olamaz. Aynı platform için destek yalnızca özgün Unsupported özniteliğin uygulandığı üst öğeye eklenebilir.
    • Aynı [SupportedOSPlatform("platformVersion")] ada sahip bir API için birden çok kez uygulanırsa platform çözümleyici yalnızca en düşük sürüme sahip olanı dikkate alır.
    • Bir API için aynı [UnsupportedOSPlatform("platformVersion")] adına sahip platform ikiden fazla uygulandığında, çözümleyici yalnızca en eski sürümlere sahip ilk iki tanesini dikkate alır.

    Uyarı

    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. Kodu çalışma zamanında koşullu olarak çağırarak bunu başarabilirsiniz. Platform denetimi yöntemlerinden birini (örneğin, Platform veyaOperatingSystem.Is<Platform>()) kullanarak istediğiniz OperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) bir üzerinde çalışıp çalışmadığınızı denetleyin. Örnek.

  • Çağrı alanını 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 kontrolüyle çağrı noktasını doğrula. Çalışma zamanında ek if bir deyimin ek yükünü istemiyorsanız, Debug.Assert(Boolean) kullanın. Ö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.

    Tavsiye

    Derleyici öncesi yönergelerle #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:

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

  • Özniteliği [UnsupportedOSPlatform("platformVersion")] için, bekçi yönteminin platformu, çağıran platformun version değerine eşit veya daha küçük 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
        }
    }
    
  • Eğer yeni netstandard API'leri kullanılamayan ancak netcoreapp veya OperatingSystem hedefleyen kodu korumanız gerekiyorsa, RuntimeInformation.IsOSPlatform API'si kullanılabilir ve çözümleyici tarafından dikkate alınacaktır. Ancak, OperatingSystem'ye eklenen yeni API'ler kadar optimize edilmemiştir. Yapıda OSPlatform platform desteklenmiyorsa, OSPlatform.Create(String) işlevini çağırarak analizcinin de dikkate aldığı platform adını aktarabilirsiniz.

    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 ek açıklamalar ekleyin ve bunları özel bir 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 belirtilen API'ler, SupportedOSPlatformAttribute ile belirtilmiş API'lere yönelik koruma olarak kullanılabilir.
  • UnsupportedOSPlatformGuardAttribute ile belirtilen API'ler, UnsupportedOSPlatformAttribute ile belirtilmiş API'lere yönelik koruma olarak kullanılabilir.

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:

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

  • [UnsupportedOSPlatform("platformVersion")] özelliği için, çağrı sitesi platformu, çağrı platformunun version'sine eşit veya daha küçük olmalıdır 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();
    }
    

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 bakınız