CA2213: Atılabilir alanlar yok edilmelidir

Özellik Değer
Kural Kimliği CA2213
Başlık Yok edilebilir alanlar yok edilmelidir
Kategori Kullanı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

System.IDisposable uygulayan bir tür, IDisposable uygulayan türlerdeki alanları bildirir. Dispose alanın yöntemi, beyan eden türün Dispose yöntemi tarafından çağrılmaz.

Kural açıklaması

Bir tür, yönetilmeyen tüm kaynaklarının yok edilmesinden sorumludur. Kural CA2213, atılabilir bir türün (yani uygulayanIDisposable) T atılabilir türün Förneği olan bir alan FT bildirip bildirmediğini denetler. İçeren türündeki Fyöntemler veya başlatıcılar içinde yerel olarak oluşturulmuş bir nesneye atanan her alan T için, kural öğesine bir çağrı FT.Disposebulmaya çalışır. T.Dispose tarafından çağrılan yöntemleri ve bir düzey daha altta yani T.Dispose tarafından çağrılan yöntemler tarafından çağrılan yöntemleri arar.

Not

Özel durumlar dışında, kural CA2213 yalnızca içeren türün yöntemleri ve başlatıcıları içerisinde yerel olarak oluşturulup bir alana atanan atılabilir nesneler için tetiklenir. Nesne, türü dışında T oluşturulur veya atanırsa, kural tetiklenmez. Bu, içeren tipin nesnenin yok edilmesinden sorumlu olmadığı durumlarda gürültüyü azaltır.

Özel durumlar

Kural CA2213, atandıkları nesne yerel olarak oluşturulmasa bile aşağıdaki türlerdeki alanlar için de tetiklenebilir:

Bu türlerden birinin nesnesini bir yapıcı metoda geçirip bir alana atamak, yeni oluşturulmuş türe bir dispose sahiplik aktarımı olduğunu gösterir. Yani, yeni oluşturulmuş tür artık nesnenin imha edilmesinden sorumludur. Nesne atılmazsa CA2213 ihlali oluşur.

İhlalleri düzeltme

Bu kuralın ihlalini düzeltmek için, IDisposable uygulayan türlerdeki alanlar üzerinde Dispose çağırın.

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

Aşağıdakiler durumunda bu kuraldan gelen bir uyarıyı engellemek güvenlidir:

  • Bayraklı tür, alan tarafından tutulan kaynağı serbest bırakmakla sorumlu değildir (başka bir ifadeyle türün yok etme sahipliği yoktur)
  • Çağrı Dispose, kural denetimlerinden daha derin bir çağrı düzeyinde gerçekleşir.
  • alanlarının tasarruf sahipliği, içeren tür tarafından elde bulundurulmaz.

Uyarıyı gizleme

Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.

#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213

Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini noneolarak ayarlayın.

[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none

Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.

Veri akışı analizini yapılandırma

Bu kural için veri akışı analizini yapılandırmak için aşağıdaki seçenekleri kullanın:

Bu seçenekleri yalnızca bu kural için, uyguladıkları tüm kurallar için veya bu kategorideki tüm kurallar için (Güvenlik) yapılandırabilirsiniz. Daha fazla bilgi için bkz. Kod kalitesi kuralı yapılandırma seçenekleri.

Örnek

Aşağıdaki kod parçacığı, IDisposable uygulayan bir tür olan TypeA'yi göstermektedir.

public class TypeA : IDisposable
{
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Dispose managed resources
        }

        // Free native resources
    }

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

    // Disposable types implement a finalizer.
    ~TypeA()
    {
        Dispose(false);
    }
}

Aşağıdaki kod parçacığı, CA2213 kuralını ihlal eden bir tür TypeB gösterir; çünkü aFieldOfADisposableType alanını atılabilir bir tür (TypeA) olarak bildirip Dispose metodunu bu alan üzerinde çağırmamaktadır.

public class TypeB : IDisposable
{
    // Assume this type has some unmanaged resources.
    TypeA aFieldOfADisposableType = new();
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            // Dispose of resources held by this instance.

            // Violates rule: DisposableFieldsShouldBeDisposed.
            // Should call aFieldOfADisposableType.Dispose();

            disposed = true;
            // Suppress finalization of this disposed instance.
            if (disposing)
            {
                GC.SuppressFinalize(this);
            }
        }
    }

    public void Dispose()
    {
        if (!disposed)
        {
            // Dispose of resources held by this instance.
            Dispose(true);
        }
    }

    // Disposable types implement a finalizer.
    ~TypeB()
    {
        Dispose(false);
    }
}

İhlali düzeltmek için atılabilir alanda Dispose() üzerinde çağrı yapın.

protected virtual void Dispose(bool disposing)
{
   if (!disposed)
   {
      // Dispose of resources held by this instance.
      aFieldOfADisposableType.Dispose();

      disposed = true;

      // Suppress finalization of this disposed instance.
      if (disposing)
      {
          GC.SuppressFinalize(this);
      }
   }
}

Ayrıca bkz.