Apa arti dari tilde sebelum nama fungsi di C #?

164

Saya melihat beberapa kode dan memiliki pernyataan ini:

~ConnectionManager()
{
    Dispose(false);
}

Kelas mengimplementasikan IDisposableantarmuka, tetapi saya tidak tahu apakah itu bagian dari tilde (~) digunakan untuk.

Keith Sirmons
sumber

Jawaban:

213

~ adalah destruktor

  1. Destructors dipanggil secara otomatis, dan tidak dapat dipanggil secara eksplisit.
  2. Destructors tidak dapat di-overload. Dengan demikian, sebuah kelas dapat memiliki, paling banyak, satu destruktor.
  3. Destructors tidak diwarisi. Dengan demikian, suatu kelas tidak memiliki destruktor selain dari yang, yang dapat dinyatakan di dalamnya.
  4. Destructors tidak dapat digunakan dengan struct. Mereka hanya digunakan dengan kelas. Sebuah instance menjadi layak untuk dihancurkan ketika kode apa pun tidak lagi dapat menggunakan instance tersebut.
  5. Eksekusi destruktor untuk instance dapat terjadi kapan saja setelah instance tersebut memenuhi syarat untuk dihancurkan.
  6. Ketika sebuah instance dihancurkan, destruktor dalam rantai pewarisannya disebut, dari yang paling diturunkan ke yang paling tidak diturunkan.

Menyelesaikan

Dalam C #, metode Menyelesaikan melakukan operasi yang destruktor C ++ standar akan lakukan. Di C #, Anda tidak menamainya Menyelesaikan - Anda menggunakan sintaksis C ++ destruktor menempatkan simbol tilde (~) di depan nama kelas.

Membuang

Lebih disukai untuk membuang objek dalam suatu Close()atau Dispose()metode yang dapat dipanggil secara eksplisit oleh pengguna kelas. Finalisasi (destruktor) dipanggil oleh GC.

The IDisposable antarmuka memberitahu dunia bahwa kelas Anda memegang ke sumber daya yang harus dibuang dan memberikan pengguna cara untuk membebaskan mereka. Jika Anda perlu menerapkan finalizer di kelas Anda, metode Buang Anda harus menggunakan GC.SuppressFinalize()metode tersebut untuk memastikan bahwa finalisasi instance Anda ditekan.

Apa yang harus digunakan?

Adalah tidak sah untuk memanggil destruktor secara eksplisit. Destruktor Anda akan dipanggil oleh pemulung. Jika Anda menangani sumber daya tak terkelola yang berharga (seperti pegangan file) yang ingin Anda tutup dan buang secepat mungkin, Anda harus mengimplementasikan antarmuka IDisposable.

Patrick Desjardins
sumber
3
Saya tidak tahu bagaimana dulu di masa lalu. Tapi sekarang destruktor diturunkan. Periksa tautan ini untuk informasi lebih lanjut (lihat contoh di akhir): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex
1
@RononDex poin 3 dari halaman yang Anda tautkan ke menyatakan "Penyelesaikan tidak dapat diwarisi" , yang bertentangan dengan komentar Anda. Memang agak membingungkan karena walaupun tidak dapat diwarisi, " Finalizemetode ini disebut secara rekursif untuk semua contoh dalam rantai pewarisan, dari yang paling diturunkan ke yang paling diturunkan" . Perhatikan bahwa itu bukan perilaku yang sama dengan yang Anda dapatkan dari perusak yang dapat diwarisi.
Mark Amery
@MarkAmery ah saya mengerti, jadi pada dasarnya mereka dipanggil dalam urutan terbalik dibandingkan dengan sesuatu yang diwarisi?
RononDex
45

Ini adalah finalizer . Sejujurnya, Anda harus sangat jarang menulis finalizer. Anda benar-benar hanya perlu menulis satu jika:

  • Anda memiliki akses langsung ke sumber daya yang tidak dikelola (misalnya melalui IntPtr) dan Anda tidak dapat menggunakan SafeHandleyang membuatnya lebih mudah
  • Anda menerapkan IDisposabledi kelas yang tidak disegel. (Preferensi saya adalah untuk menyegel kelas kecuali mereka dirancang untuk pewarisan.) Penyelesai adalah bagian dari pola Buang kanonik dalam kasus tersebut.
Jon Skeet
sumber
9

Ini digunakan untuk menunjukkan destruktor untuk kelas.

torial
sumber
12
Keduanya benar, tergantung pada spesifikasi C # yang Anda baca. MS yang terbaru (unified C # 3.0) merujuk mereka sebagai destruktor (mis. Bagian 10.13) tetapi spesifikasi ECMA menyebut mereka sebagai finalizer.
Jon Skeet
@ 1800INFORMATION: Elemen sintaksis secara tepat disebut destructor. Jika kelas memiliki destruktor, kompiler C # akan secara otomatis menghasilkan finalizer yang mencakup try/finallyblok yang umumnya tidak berguna yang memastikan bahwa Finalizemetode induk dipanggil. Sebagian besar hal yang benar untuk destruktor benar untuk finalizer, dan sebaliknya, tetapi kata-kata berarti hal yang sedikit berbeda.
supercat
4

Sama seperti C ++, itu adalah destructor; Namun dalam C # Anda tidak menyebutnya secara eksplisit, itu dipanggil ketika objek dikumpulkan.

Santiago Palladino
sumber
3

Lihat Destructors (Panduan Pemrograman C #) . Perlu diketahui, bahwa, tidak seperti C ++, programmer tidak memiliki kendali atas kapan destructor dipanggil karena ini ditentukan oleh pengumpul sampah.

Jeff Stong
sumber
1

~ biasanya mewakili dekonstruktor. yang dijalankan tepat sebelum objek mati.

Berikut ini adalah deskripsi dari deconstructors C # yang saya temukan

stephenbayer
sumber
4
istilah yang benar adalah destruktor / finalizer, bukan dekonstruktor. Dekonstruktor berarti sintaks untuk mendekonstruksi konstruktor.
Eriawan Kusumawardhono