Aracılığıyla paylaş


CA1416: Platform uyumluluğunu doğrulama

Özellik Değer
Kural Kimliği CA1416
Başlık Platform uyumluluğunu doğrula
Kategori Birlikte çalışabilirlik
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 9'da varsayılan olarak etkin Uyarı olarak

Neden

Platforma özgü bir API farklı bir platform bağlamında kullanılıyorsa veya platform doğrulanmamışsa (platformdan bağımsız) ihlaller bildirilir. Projenin hedef platformu için desteklenmeyen bir API kullanıldığında da ihlaller bildirilir.

Bu kural varsayılan olarak yalnızca .NET 5 veya üzerini hedefleyen projeler için etkinleştirilir. Ancak, diğer çerçeveleri hedefleyen projeler için etkinleştirebilirsiniz.

Kural açıklaması

.NET 5, SupportedOSPlatformAttribute platforma özgü API'lere ek açıklama eklemek için yeni öznitelikler ve UnsupportedOSPlatformAttributeekledi. Her iki öznitelik de platform adının bir parçası olarak sürüm numaralarıyla veya sürüm numaraları olmadan örneklenebilir. Bunlar farklı platformlarla birden çok kez de uygulanabilir.

  • Açıklama eklemeyen bir API'nin tüm işletim sistemi (OS) platformlarında çalıştığı kabul edilir.
  • ile [SupportedOSPlatform("platformName")] işaretlenmiş bir API'nin yalnızca belirtilen işletim sistemi platformlarına taşınabilir olduğu kabul edilir. Platform başka bir platformun alt kümesiyse, özniteliği bu platformun da desteklendiğini gösterir.
  • ile [UnsupportedOSPlatform("platformName")] işaretlenen bir API, belirtilen işletim sistemi platformlarında desteklenmemiş olarak kabul edilir. Platform başka bir platformun alt kümesiyse, özniteliği bu platformun da desteklenmediğini gösterir.

ve [UnsupportedOSPlatform] özniteliklerini tek bir API'de birleştirebilirsiniz[SupportedOSPlatform]. Bu durumda, aşağıdaki kurallar geçerlidir:

  • İzin ver 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. Listede aynı platforma sahip bir [UnsupportedOSPlatform] öznitelik olabilir, ancak yalnızca api'nin bu sürümden kaldırıldığını belirten daha yüksek bir sürüme sahip olabilir.
  • Reddetme 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. Listenin aynı platforma sahip bir [SupportedOSPlatform] özniteliği olabilir, ancak yalnızca daha yüksek bir sürüme sahip olabilir ve bu, API'nin bu sürümden bu yana desteklendiğini belirtir.
  • Tutarsız liste. Bazı platformlar için en düşük sürüm ancak [UnsupportedOSPlatform] diğer platformlar içinse[SupportedOSPlatform], bu birleşim tutarsız olarak kabul edilir. API'de bazı ek açıklamalar yoksayılır. Gelecekte, tutarsızlık durumunda uyarı üreten bir çözümleyici tanıtabiliriz.

Farklı bir platform bağlamından bu özniteliklerle açıklama ek açıklamalı bir API'ye erişiyorsa CA1416 ihlallerini görebilirsiniz.

TFM hedef platformları

Çözümleyici, veya <TargetFrameworks>gibi <TargetFramework> MSBuild özelliklerinden hedef çerçeve adı (TFM) hedef platformlarını denetlemez. TFM'nin bir hedef platformu varsa, .NET SDK'sı çözümleyici tarafından kullanılan AssemblyInfo.cs dosyasına hedeflenen platform adını içeren bir SupportedOSPlatform öznitelik ekler. Örneğin, TFM ise net5.0-windows10.0.19041SDK ö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 özellik <GenerateAssemblyInfo> olarak falseayarlanır), gerekli derleme düzeyi SupportedOSPlatform özniteliği SDK 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.

Ihlal

  • Yalnızca belirli bir platformda ([SupportedOSPlatform("platformName")]) desteklenen bir API'ye diğer platformlarda erişilebilen koddan erişilirse şu ihlali görürsünüz: 'platformName' üzerinde 'API' desteklenir.

    // An API supported only on Linux.
    [SupportedOSPlatform("linux")]
    public void LinuxOnlyApi() { }
    
    // API is supported on Windows, iOS from version 14.0, and MacCatalyst from version 14.0.
    [SupportedOSPlatform("windows")]
    [SupportedOSPlatform("ios14.0")] // MacCatalyst is a superset of iOS, therefore it's also supported.
    public void SupportedOnWindowsIos14AndMacCatalyst14() { }
    
    public void Caller()
    {
        LinuxOnlyApi(); // This call site is reachable on all platforms. 'LinuxOnlyApi()' is only supported on: 'linux'
    
        SupportedOnWindowsIos14AndMacCatalyst14(); // This call site is reachable on all platforms. 'SupportedOnWindowsIos14AndMacCatalyst14()'
                                                   // is only supported on: 'windows', 'ios' 14.0 and later, 'MacCatalyst' 14.0 and later.
    }
    

    Not

    İhlal yalnızca proje desteklenen platformu (net5.0-differentPlatform ) hedeflemiyorsa oluşur. Bu, çok hedefli projeler için de geçerlidir. Proje belirtilen platformu (net5.0-platformName) hedeflerse ve proje için AssemblyInfo.cs dosya oluşturma etkinleştirilirse ihlal oluşmaz.

  • Desteklenmeyen platformu hedefleyen bir bağlamdan ile ilişkilendirilen [UnsupportedOSPlatform("platformName")] bir API'ye erişmek bir ihlale neden olabilir: 'platformName' üzerinde 'API' desteklenmez.

    // An API not supported on Android but supported on all other platforms.
    [UnsupportedOSPlatform("android")]
    public void DoesNotWorkOnAndroid() { }
    
    // An API was unsupported on Windows until version 10.0.18362.
    // The API is considered supported everywhere else without constraints.
    [UnsupportedOSPlatform("windows")]
    [SupportedOSPlatform("windows10.0.18362")]
    public void StartedWindowsSupportFromCertainVersion() { }
    
    public void Caller()
    {
        DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android'
    
        StartedWindowsSupportFromCertainVersion(); // This call site is reachable on all platforms. 'StartedWindowsSupportFromCertainVersion()' is unsupported on: 'windows' 10.0.18362 and before
    }
    

Not

Desteklenmeyen platformu hedeflemeyen bir uygulama oluşturuyorsanız herhangi bir ihlal almazsınız. İhlal yalnızca aşağıdaki durumlarda oluşur:

  • Proje, desteklenmeyen olarak özniteliklendirilen platformu hedefler.

  • platformName varsayılan MSBuild <SupportedPlatform> öğeleri grubuna eklenir.

  • platformName , MSBuild <SupportedPlatform> öğeleri grubuna el ile eklenir.

    <ItemGroup>
        <SupportedPlatform Include="platformName" />
    </ItemGroup>
    

İhlalleri düzeltme

İhlallerle başa çıkmanın önerilen yolu, yalnızca uygun bir platformda çalışırken platforma özgü API'leri çağırdığınızdan emin olmaktır. Kullanarak ve çoklu hedefleme kullanarak #if derleme zamanında kodu dışlayarak veya çalışma zamanında kodu koşullu olarak çağırarak bunu başarabilirsiniz. Çözümleyici, ve System.Runtime.InteropServices.RuntimeInformation.IsOSPlatformsınıfında platform korumalarını OperatingSystem tanır.

  • veya ile SupportedOSPlatformGuardAttribute UnsupportedOSPlatformGuardAttributeek açıklama ekli standart platform guard yöntemleri veya özel koruma API'leri ile çağrı sitesini çevreleyerek ihlalleri bastırın.

    // An API supported only on Linux.
    [SupportedOSPlatform("linux")]
    public void LinuxOnlyApi() { }
    
    // API is supported on Windows, iOS from version 14.0, and MacCatalyst from version 14.0.
    [SupportedOSPlatform("windows")]
    [SupportedOSPlatform("ios14.0")] // MacCatalyst is a superset of iOS, therefore it's also supported.
    public void SupportedOnWindowsIos14AndMacCatalyst14() { }
    
    public void Caller()
    {
        LinuxOnlyApi(); // This call site is reachable on all platforms. 'LinuxOnlyApi()' is only supported on: 'linux'.
    
        SupportedOnWindowsIos14AndMacCatalyst14(); // This call site is reachable on all platforms. 'SupportedOnWindowsIos14AndMacCatalyst14()'
                                                   // is only supported on: 'windows', 'ios' 14.0 and later, 'MacCatalyst' 14.0 and later.
    }
    
    [SupportedOSPlatformGuard("windows")]  // The platform guard attributes used
    [SupportedOSPlatformGuard("ios14.0")]
    private readonly bool _isWindowOrIOS14 = OperatingSystem.IsWindows() || OperatingSystem.IsIOSVersionAtLeast(14);
    
    // The warnings are avoided using platform guard methods.
    public void Caller()
    {
        if (OperatingSystem.IsLinux()) // standard guard examples
        {
            LinuxOnlyApi(); // no diagnostic
        }
    
        if (OperatingSystem.IsIOSVersionAtLeast(14))
        {
            SupportedOnWindowsAndIos14(); // no diagnostic
        }
    
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            SupportedOnWindowsAndIos14(); // no diagnostic
        }
    
        if (_isWindowOrMacOS14) // custom guard example
        {
            SupportedOnWindowsAndIos14(); // no diagnostic
        }
    }
    
    // An API not supported on Android but supported on all other platforms.
    [UnsupportedOSPlatform("android")]
    public void DoesNotWorkOnAndroid() { }
    
    // An API was unsupported on Windows until version 10.0.18362.
    // The API is considered supported everywhere else without constraints.
    [UnsupportedOSPlatform("windows")]
    [SupportedOSPlatform("windows10.0.18362")]
    public void StartedWindowsSupportFromCertainVersion();
    
    public void Caller()
    {
        DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android'
    
        StartedWindowsSupportFromCertainVersion(); // This call site is reachable on all platforms. 'StartedWindowsSupportFromCertainVersion()' is unsupported on: 'windows' 10.0.18362 and before.
    }
    
    [UnsupportedOSPlatformGuard("android")] // The platform guard attribute
    bool IsNotAndroid => !OperatingSystem.IsAndroid();
    
    public void Caller()
    {
        if (!OperatingSystem.IsAndroid()) // using standard guard methods
        {
            DoesNotWorkOnAndroid(); // no diagnostic
        }
    
        // Use the && and || logical operators to guard combined attributes.
        if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(10, 0, 18362))
        {
            StartedWindowsSupportFromCertainVersion(); // no diagnostic
        }
    
        if (IsNotAndroid) // custom guard example
        {
            DoesNotWorkOnAndroid(); // no diagnostic
        }
    }
    
  • Çözümleyici, desteklenmeyen platformlarda System.Diagnostics.Debug.Assert kodun ulaşılmasını önlemenin bir aracı olarak da dikkate alır. kullanmak Debug.Assert , denetimin isterseniz yayın derlemelerinin kırpılmasını sağlar.

    // An API supported only on Linux.
    [SupportedOSPlatform("linux")]
    public void LinuxOnlyApi() { }
    
    public void Caller()
    {
        Debug.Assert(OperatingSystem.IsLinux());
    
        LinuxOnlyApi(); // No diagnostic
    }
    
  • Kendi API'lerinizi platforma özgü olarak işaretlemeyi ve gereksinimleri arayanlarınıza etkili bir şekilde iletmeyi seçebilirsiniz. Platform özniteliklerini aşağıdaki API'lerden herhangi birine uygulayabilirsiniz:

    • Türler
    • Üyeler (yöntemler, alanlar, özellikler ve olaylar)
    • Bütünleştirilmiş Kodlar
    [SupportedOSPlatform("windows")]
    [SupportedOSPlatform("ios14.0")]
    public void SupportedOnWindowsAndIos14() { }
    
    [SupportedOSPlatform("ios15.0")] // call site version should be equal to or higher than the API version
    public void Caller()
    {
        SupportedOnWindowsAndIos14(); // No diagnostics
    }
    
    [UnsupportedOSPlatform("windows")]
    [SupportedOSPlatform("windows10.0.18362")]
    public void StartedWindowsSupportFromCertainVersion();
    
    [UnsupportedOSPlatform("windows")]
    [SupportedOSPlatform("windows10.0.18362")]
    public void Caller()
    {
        StartedWindowsSupportFromCertainVersion(); // No diagnostics
    }
    
  • Derleme düzeyi veya tür düzeyi özniteliği uygulandığında, derleme veya tür içindeki tüm üyeler platforma özgü olarak kabul edilir.

    [assembly:SupportedOSPlatform("windows")]
    public namespace ns
    {
        public class Sample
        {
            public void SupportedOnWindows() { }
    
            public void Caller()
            {
                SupportedOnWindows(); // No diagnostic as call site and calling method both windows only
            }
        }
    }
    

Uyarıların ne zaman bastırılması gerekiyor?

Uygun bir platform bağlamı veya koruması olmadan platforma özgü API'lere başvurmak önerilmez. Ancak, veya NoWarn derleyici bayrağını kullanarak veya kuralın önem derecesini none bir .editorconfig dosyasında olarak ayarlayarak bu tanılamaları gizleyebilirsiniz.#pragma

[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }

public void Caller()
{
#pragma warning disable CA1416
    LinuxOnlyApi();
#pragma warning restore CA1416
}

Çözümlemek için kod yapılandırma

Çözümleyici varsayılan olarak yalnızca .NET 5 veya üzerini hedefleyen ve AnalysisLevel değeri 5 veya üzeri olan projeler için etkinleştirilir. Projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyerek daha düşük net5.0 hedef çerçeveler için etkinleştirebilirsiniz:

dotnet_code_quality.enable_platform_analyzer_on_pre_net5_target = true

Ayrıca bkz.