CA1063: Terapkan IDisposable dengan benar
Properti | Nilai |
---|---|
ID Aturan | CA1063 |
Judul | Menerapkan IDisposable dengan benar |
Golongan | Desain |
Perbaikan bersifat disruptif atau non-disruptif | Non-disruptif |
Diaktifkan secara default di .NET 8 | Tidak |
Penyebab
Antarmuka System.IDisposable tidak diimplementasikan dengan benar. Kemungkinan alasan untuk ini meliputi:
- IDisposable diisi ulang di kelas .
Finalize
ditimpa lagi.Dispose()
ditimpa.- Metode
Dispose()
ini tidak publik, disegel, atau bernama Buang. Dispose(bool)
tidak dilindungi, virtual, atau tidak tersegel.- Dalam jenis yang tidak disegel,
Dispose()
harus memanggilDispose(true)
. - Untuk jenis yang tidak disegel,
Finalize
implementasi tidak memanggil atau keduanyaDispose(bool)
atau finalizer kelas dasar.
Pelanggaran salah satu pola ini memicu peringatan CA1063.
Setiap jenis tidak tersegel yang menyatakan dan mengimplementasikan IDisposable antarmuka harus menyediakan metodenya sendiri protected virtual void Dispose(bool)
. Dispose()
harus memanggil Dispose(true)
, dan finalizer harus memanggil Dispose(false)
. Jika Anda membuat jenis yang tidak disegel yang mendeklarasikan dan mengimplementasikan IDisposable antarmuka, Anda harus menentukan Dispose(bool)
dan memanggilnya. Untuk informasi selengkapnya, lihat Membersihkan sumber daya yang tidak dikelola (panduan.NET) dan Menerapkan metode Buang.
Secara default, aturan ini hanya melihat jenis yang terlihat secara eksternal, tetapi ini dapat dikonfigurasi.
Deskripsi aturan
Semua IDisposable jenis harus menerapkan pola Buang dengan benar.
Cara memperbaiki pelanggaran
Periksa kode Anda dan tentukan resolusi mana yang akan memperbaiki pelanggaran ini:
Hapus IDisposable dari daftar antarmuka yang diimplementasikan oleh jenis Anda, dan ambil alih kelas dasar Buang implementasi sebagai gantinya.
Hapus finalizer dari jenis Anda, ambil alih Dispose(bool disposing), dan letakkan logika finalisasi di jalur kode tempat 'membuang' salah.
Ambil alih Buang(pembuangan bool), dan letakkan logika buang di jalur kode tempat 'membuang' adalah benar.
Pastikan Bahwa Dispose() dinyatakan sebagai publik dan disegel.
Ganti nama metode pembuangan Anda menjadi Buang dan pastikan metode tersebut dinyatakan sebagai publik dan disegel.
Pastikan Bahwa Dispose(bool) dinyatakan sebagai dilindungi, virtual, dan tidak tersegel.
Ubah Dispose() sehingga memanggil Dispose(true), lalu memanggil pada instans SuppressFinalize objek saat ini (
this
, atauMe
di Visual Basic), lalu kembali.Ubah finalizer Anda sehingga memanggil Dispose(false) lalu kembali.
Jika Anda membuat jenis tidak tersegel yang menyatakan dan mengimplementasikan IDisposable antarmuka, pastikan bahwa implementasi IDisposable mengikuti pola yang dijelaskan sebelumnya di bagian ini.
Kapan harus menekan peringatan
Jangan menyembunyikan peringatan dari aturan ini.
Catatan
Anda mungkin melihat peringatan positif palsu dari aturan ini jika semua hal berikut ini berlaku:
- Anda menggunakan Visual Studio 2022 versi 17.5 atau yang lebih baru dengan versi .NET SDK yang lebih lama, yaitu, .NET 6 atau yang lebih lama.
- Anda menggunakan penganalisis dari .NET 6 SDK atau versi paket penganalisis yang lebih lama, seperti Microsoft.CodeAnalysis.FxCopAnalyzers.
- Anda memiliki atribut pada implementasi Anda
IDispose
.
Dalam hal ini, aman untuk menekan peringatan positif palsu. Positif palsu disebabkan oleh perubahan yang melanggar dalam pengkompilasi C#. Pertimbangkan untuk menggunakan penganalisis yang lebih baru yang berisi perbaikan untuk peringatan positif palsu. Tingkatkan ke Microsoft.CodeAnalysis.NetAnalyzers versi 7.0.0-preview1.22464.1 atau yang lebih baru atau gunakan penganalisis dari .NET 7 SDK.
Mengonfigurasi kode yang akan dianalisis
Gunakan opsi berikut untuk mengonfigurasi bagian mana dari codebase Anda yang akan menjalankan aturan ini.
Anda dapat mengonfigurasi opsi ini hanya untuk aturan ini, untuk semua aturan yang berlaku untuknya, atau untuk semua aturan dalam kategori ini (Desain) yang berlaku untuk aturan ini. Untuk informasi selengkapnya, lihat Opsi konfigurasi aturan kualitas kode.
Menyertakan permukaan API tertentu
Anda dapat mengonfigurasi bagian mana dari basis kode yang akan menjalankan aturan ini, berdasarkan aksesibilitasnya. Misalnya, untuk menentukan bahwa aturan hanya boleh dijalankan pada permukaan API non-publik, tambahkan pasangan kunci-nilai berikut ke file .editorconfig di proyek Anda:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Contoh kode semu
Kode semu berikut memberikan contoh umum tentang bagaimana Dispose(bool)
harus diimplementasikan di kelas yang menggunakan sumber daya terkelola dan asli.
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);
}
}
Baca juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk