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 9 | No |
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 FT
sekali pakai . Untuk setiap bidang F
yang diberi objek yang dibuat secara lokal dalam metode atau penginisialisasi dari jenis T
yang 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.
Mengonfigurasi analisis aliran data
Gunakan opsi berikut untuk mengonfigurasi analisis aliran data untuk aturan ini:
- interprocedural_analysis_kind
- max_interprocedural_lambda_or_local_function_call_chain
- max_interprocedural_method_call_chain
- points_to_analysis_kind
- copy_analysis
- sufficient_IterationCount_for_weak_KDF_algorithm
Anda dapat mengonfigurasi opsi ini hanya untuk aturan ini, untuk semua aturan yang berlaku, atau untuk semua aturan dalam kategori ini (Security) yang berlaku untuk aturan tersebut. Untuk informasi selengkapnya, lihat opsi konfigurasi aturan kualitas 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);
}
}
}