CA1063: IDisposable'ı doğru uygulayın

Özellik Değer
Kural Kimliği CA1063
Başlık IDisposable'ı doğru uygulayın
Kategori Tasarım
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 8'de varsayılan olarak etkin Hayır

Neden

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

  • IDisposable sınıfına yeniden eklenir.
  • Finalize yeniden geçersiz kılınabilir.
  • Dispose() geçersiz kılınmış.
  • yöntemi Dispose() ortak, korumalı veya Dispose olarak adlandırılmaz.
  • Dispose(bool) korumalı, sanal veya korumasız değildir.
  • Korumasız türlerde çağrısı Dispose()Dispose(true)yapılmalıdır.
  • Korumasız türler için, Finalize uygulama ya da her ikisini Dispose(bool) ya da temel sınıf sonlandırıcı çağırmaz.

Bu desenlerden herhangi birinin ihlali ca1063 uyarı tetikler.

Arabirimini bildiren ve uygulayan IDisposable korumasız her tür 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ı da öğesini çağırmalıdır Dispose(false). Arabirimi bildiren ve uygulayan IDisposable korumasız bir tür oluşturursanız, tanımlamanız Dispose(bool) ve çağırmanız gerekir. Daha fazla bilgi için bkz . Yönetilmeyen kaynakları temizleme (.NET kılavuzu) ve Dispose yöntemi uygulama.

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.

  • Sonlandırıcıyı türünüzden kaldırın, Dispose(bool disposing) öğesini geçersiz kılın ve sonlandırıcı mantığını 'yok etme'nin false olduğu kod yoluna 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 korumalı olduğundan emin olun.

  • Dispose yönteminizi Dispose olarak yeniden adlandırın ve genel olarak bildirildiğinden ve korumalı olduğundan emin olun.

  • Dispose(bool) öğesinin korumalı, sanal ve korumasız olarak bildirildiğinden emin olun.

  • Dispose() öğesini dispose(true) olarak çağırıp geçerli nesne örneğinde (thisveya Me Visual Basic'te) çağırıp SuppressFinalize döndürdüğü şekilde değiştirin.

  • Sonlandırıcınızı Dispose(false) öğesini çağırıp döndürdüğü şekilde değiştirin.

  • 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.

Dekont

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ızla ilgili öznitelikleriniz IDispose vardır.

Bu durumda hatalı pozitif uyarıyı bastırmak güvenlidir. Hatalı pozitifler, C# derleyicisindeki hataya neden olan bir değişiklik nedeniyledir. 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.

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

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

Bu kuralın üzerinde çalıştırılacak kod tabanınızın hangi bölümlerini erişilebilirliklerine göre 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

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.