Bagikan melalui


CA2213: Bidang sekali pakai harus dibuang

Properti Nilai
ID Aturan CA2213
Judul Bidang sekali pakai harus dibuang
Golongan Penggunaan
Perbaikan bersifat disruptif atau non-disruptif Non-disruptif
Diaktifkan secara default di .NET 8 Tidak

Penyebab

Jenis yang mengimplementasikan mendeklarasikan System.IDisposable bidang yang merupakan jenis yang juga mengimplementasikan IDisposable. Metode Dispose bidang tidak dipanggil dengan Dispose metode jenis deklarasikan.

Deskripsi aturan

Jenis bertanggung jawab untuk membuang semua sumber daya yang tidak dikelola. Aturan CA2213 memeriksa untuk melihat apakah jenis sekali pakai (yaitu, yang mengimplementasikan IDisposable) T mendeklarasikan bidang F yang merupakan instans dari jenis FTsekali pakai . Untuk setiap bidang F yang diberi objek yang dibuat secara lokal dalam metode atau penginisialisasi dari jenis Tyang berisi , aturan mencoba menemukan panggilan ke FT.Dispose. Aturan mencari metode yang dipanggil oleh T.Dispose dan satu tingkat lebih rendah (yaitu, metode yang dipanggil oleh metode yang dipanggil oleh T.Dispose).

Catatan

Selain kasus khusus, aturan CA2213 hanya diaktifkan untuk bidang yang diberi objek sekali pakai yang dibuat secara lokal dalam metode dan inisialisasi jenis yang berisi. Jika objek dibuat atau ditetapkan di luar jenis T, aturan tidak diaktifkan. Ini mengurangi kebisingan untuk kasus di mana jenis yang berisi tidak memiliki tanggung jawab untuk membuang objek.

Kasus khusus

Aturan CA2213 juga dapat diaktifkan untuk bidang dari jenis berikut meskipun objek yang ditetapkan tidak dibuat secara lokal:

Meneruskan objek dari salah satu jenis ini ke konstruktor lalu menetapkannya ke bidang menunjukkan transfer kepemilikan buang ke jenis yang baru dibangun. Artinya, jenis yang baru dibangun sekarang bertanggung jawab untuk membuang objek. Jika objek tidak dibuang, pelanggaran CA2213 terjadi.

Cara memperbaiki pelanggaran

Untuk memperbaiki pelanggaran aturan ini, panggil Dispose bidang yang merupakan jenis yang mengimplementasikan IDisposable.

Kapan harus menekan peringatan

Aman untuk menyembunyikan peringatan dari aturan ini jika:

  • Jenis yang ditandai tidak bertanggung jawab untuk merilis sumber daya yang dipegang oleh bidang (yaitu, jenis tidak memiliki kepemilikan buang)
  • Panggilan ke Dispose terjadi pada tingkat panggilan yang lebih dalam daripada pemeriksaan aturan
  • kepemilikan buang bidang tidak dipegang oleh jenis yang berisi.

Menyembunyikan peringatan

Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.

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

Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none dalam file konfigurasi.

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

Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.

Contoh

Cuplikan berikut menunjukkan jenis TypeA yang mengimplementasikan 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);
    }
}

Cuplikan berikut menunjukkan jenis TypeB yang melanggar aturan CA2213 dengan mendeklarasikan bidang aFieldOfADisposableType sebagai tipe sekali pakai (TypeA) dan tidak memanggil Dispose pada bidang .

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);
    }
}

Untuk memperbaiki pelanggaran, panggil Dispose() bidang sekali pakai:

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);
      }
   }
}

Baca juga