CA2213: Atılabilen alanlar atılmalıdır

Özellik Değer
Kural Kimliği CA2213
Başlık Atılabilen alanlar atılmalıdır
Kategori Kullanım
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 8'de varsayılan olarak etkin Hayır

Neden

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

Kural açıklaması

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

Dekont

Özel durumlar dışında, kural CA2213 yalnızca içeren türün yöntemleri ve başlatıcıları içinde yerel olarak oluşturulmuş bir atılabilir nesne atanmış alanlar için tetiklenir. Nesne türü dışında Toluşturulur veya atanırsa, kural tetiklenmez. Bu, içeren türün nesnenin atılmasıyla ilgili sorumluluğun 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 oluşturucuya geçirip bir alana atamak, yeni oluşturulan türe bir atma sahiplik aktarımını gösterir. Yani, yeni yapılan tür artık nesnenin atılmasından sorumludur. Nesne atılmazsa CA2213 ihlali oluşur.

İhlalleri düzeltme

Bu kuralın ihlalini düzeltmek için, uygulayan IDisposabletürlerdeki alanları çağırınDispose.

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 atma sahipliği yoktur)
  • çağrısı Dispose , kural denetimlerinden daha derin bir çağrı düzeyinde gerçekleşir
  • alanlarının atma sahipliği, içeren tür tarafından tutulmaz.

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.

Örnek

Aşağıdaki kod parçacığında uygulayan bir tür TypeA gösterilmektedir IDisposable.

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ığı, bir alanı atılabilir bir tür (TypeA) olarak bildirerek ve alanı aFieldOfADisposableType çağırmayarak Dispose CA2213 kuralını ihlal eden bir tür TypeB gösterir.

public class TypeB : IDisposable
{
    // Assume this type has some unmanaged resources.
    TypeA aFieldOfADisposableType = new TypeA();
    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 alanı arayın Dispose() :

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.