CA1063: IDisposable'ı doğru uygulayın

Özellik Değer
Kural Kimliği CA1063
Başlık IDisposable'ı doğru uygulayın
Kategori Tasarım
Düzeltme bozucu ya da bozmayan olabilir Kesintisiz
.NET 10'da varsayılan olarak etkin Hayır
Geçerli diller C# ve Visual Basic

Neden

Arabirim System.IDisposable doğru uygulanmadı. Bunun olası nedenleri şunlardır:

  • IDisposable sınıfında yeniden uygulanır.
  • Finalize yeniden geçersiz kılınabilir.
  • Dispose() geçersiz kılınmış.
  • yöntemi Dispose() genel, mühürlü ya da Dispose olarak adlandırılmıyor.
  • Dispose(bool) korumalı, sanal veya mühürsüz değildir.
  • Mühürsüz türlerde, Dispose()Dispose(true) çağrısı yapmalıdır.
  • Mühürlenmemiş türler için, Finalize uygulaması ne Dispose(bool)’yi ne de temel sınıf sonlandırıcısını çağırır.

Bu desenlerden herhangi birinin ihlali, CA1063 uyarısını tetikler.

Kapatılmamış her tür, IDisposable arabirimini bildiren ve uygulayan, kendi protected virtual void Dispose(bool) yöntemini sağlamalıdır. Dispose() çağrısı Dispose(true) yapmalıdır ve sonlandırıcı Dispose(false) öğesini çağırmalıdır. IDisposable arabirimini bildirip uygulayan mühürsüz bir tür oluşturursanız, tanımlamanız ve çağırmanız gereken Dispose(bool)'yi tanımlamanız gerekir. Daha fazla bilgi için Yönetilmeyen kaynakları temizleme (.NET kılavuzu) ve Dispose yöntemi uygulama başlıklarına bakın.

Varsayılan olarak, bu kural yalnızca dışarıdan görünen türlere bakar, ancak bu yapılandırılabilir.

Kural açıklaması

Tüm IDisposable türler Dispose desenini doğru şekilde uygulamalıdır.

İhlalleri düzeltme

Kodunuzu inceleyin ve aşağıdaki çözümlerden hangisinin bu ihlali düzelteceğini belirleyin:

  • Türünüz tarafından uygulanan arabirimler listesinden kaldırın IDisposable ve bunun yerine temel sınıfı Dispose uygulamasını geçersiz kılın.

  • Türünüzden sonlandırıcıyı kaldırın, Dispose(bool disposing) yöntemini geçersiz kılın ve sonlandırma mantığını 'disposing' false olduğunda kod akışına yerleştirin.

  • Dispose(bool disposing) öğesini geçersiz kılın ve dispose mantığını 'disposing' değerinin true olduğu kod yoluna yerleştirin.

  • Dispose() öğesinin genel olarak bildirildiğinden ve sealed olduğundan emin olun.

  • Dispose yönteminizi Dispose olarak yeniden adlandırın ve genel ve sealed olarak tanımlandığından emin olun.

  • Dispose(bool) öğesinin korumalı, sanal ve mühürlenmemiş olarak bildirildiğinden emin olun.

  • Dispose() yöntemini Dispose(true) çağrısında bulunacak, ardından geçerli nesne örneğinde (SuppressFinalize veya Visual Basic'te this) Me metodunu çağıracak şekilde değiştirin ve ardından döndürün.

  • Sonlandırıcınızı Dispose(false) öğesini çağırıp döndüren şekilde değiştirdiğinizden emin olun.

  • Arabirimini bildiren ve uygulayan IDisposable korumasız bir tür oluşturursanız, uygulamasının IDisposable bu bölümün önceki bölümlerinde açıklanan desene uydığından emin olun.

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

Bu kuraldan uyarıyı bastırmayın.

Not

Aşağıdakilerin tümü geçerliyse bu kuraldan hatalı pozitif uyarılar görebilirsiniz:

  • Visual Studio 2022 sürüm 17.5 veya üzerini .NET SDK'nın daha eski bir sürümüyle ( .NET 6 veya önceki bir sürüm) kullanıyorsunuz.
  • .NET 6 SDK'sından çözümleyicileri veya çözümleyici paketlerinin Microsoft.CodeAnalysis.FxCopAnalyzers gibi eski bir sürümünü kullanıyorsunuz.
  • Uygulamanızın IDispose üzerinde öznitelikler bulunmaktadır.

Bu durumda hatalı pozitif uyarıyı bastırmak güvenlidir. Hatalı pozitifler, C# derleyicisindeki büyük bir değişiklikten kaynaklanmaktadır. Hatalı pozitif uyarıların düzeltmesini içeren daha yeni bir çözümleyici kullanmayı düşünün. Microsoft.CodeAnalysis.NetAnalyzers sürüm 7.0.0-preview1.22464.1 veya daha yeni bir sürüme yükseltin veya .NET 7 SDK'sından çözümleyicileri kullanın.

Kod çözümleme için konfigüre et

Bu kuralın kod tabanınızın hangi bölümlerinde çalıştırılacaklarını yapılandırmak için aşağıdaki seçeneği kullanın.

Bu seçeneği yalnızca bu kural, geçerli olduğu tüm kurallar veya bu kategorideki (Tasarım) tüm kurallar için yapılandırabilirsiniz. Daha fazla bilgi için bkz . Kod kalitesi kuralı yapılandırma seçenekleri.

Belirli API yüzeylerini ekleme

api_surface seçeneğini ayarlayarak, bu kuralın erişilebilirliği temelinde kod tabanınızın hangi bölümlerinde çalıştırılacaklarını yapılandırabilirsiniz. Örneğin, kuralın yalnızca genel olmayan API yüzeyinde çalıştırılması gerektiğini belirtmek için projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Not

XXXX CAXXXX bölümünü geçerli kuralın kimliğiyle değiştirin.

Sahte kod örneği

Aşağıdaki sahte kod, yönetilen ve yerel kaynakları kullanan bir sınıfta nasıl Dispose(bool) uygulanması gerektiğine ilişkin genel bir örnek sağlar.

public class Resource : IDisposable
{
    private bool isDisposed;
    private IntPtr nativeResource = Marshal.AllocHGlobal(100);
    private AnotherResource managedResource = new AnotherResource();

    // Dispose() calls Dispose(true)
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    // The bulk of the clean-up code is implemented in Dispose(bool)
    protected virtual void Dispose(bool disposing)
    {
        if (isDisposed) return;

        if (disposing)
        {
            // free managed resources
            managedResource.Dispose();
        }

        // free native resources if there are any.
        if (nativeResource != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(nativeResource);
            nativeResource = IntPtr.Zero;
        }

        isDisposed = true;
    }

    // NOTE: Leave out the finalizer altogether if this class doesn't
    // own unmanaged resources, but leave the other methods
    // exactly as they are.
    ~Resource()
    {
        // Finalizer calls Dispose(false)
        Dispose(false);
    }
}

Ayrıca bkz.