Câu trả lời ngắn gọn
Chỉ có thể có MỘT (1) destructor trong một class.
Cú pháp Destructor
public class Demo
{
// Chỉ được KHÔNG THAM SỐ
~Demo()
{
// Cleanup statements...
Console.WriteLine("Finalizer called");
}
}
Đặc điểm Destructor (Finalizer)
- Không tham số: Không thể truyền đối số.
- Không access modifier: Không public/private/protected.
- Bắt đầu bằng
~: Tilde symbol theo sau tên class. - Không thể gọi trực tiếp: Chỉ GC gọi.
- Không thể định nghĩa trong struct: Chỉ class.
- Gọi ngầm
base.Finalize(): Trong finally block.
Ví dụ: Chỉ một destructor
class Demo
{
~Demo()
{
Console.WriteLine("Finalizer 1");
}
// ❌ LỖI COMPILE: 'Demo' already defines a member called '~Demo'
// ~Demo()
// {
// Console.WriteLine("Finalizer 2");
// }
}
class Program
{
static void Main()
{
var d = new Demo();
d = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadLine();
}
}
Lỗi compile nếu khai báo 2 destructor
Error CS0111: Type 'Demo' already defines a member called '~Demo' with the same parameter types
Destructor vs Finalize
Destructor syntax ~ClassName() được compiler dịch thành:
protected override void Finalize()
{
try
{
// Your cleanup code
}
finally
{
base.Finalize(); // Luôn gọi base.Finalize()
}
}
Khi nào dùng Destructor/Finalize?
- Chỉ khi có unmanaged resources (file handle, socket, COM object, unmanaged memory).
- Managed resources (objects) → GC tự dọn dẹp, không cần finalizer.
- Ưu tiên
IDisposable+usingcho deterministic cleanup.
SafeHandle - Thay thế hiện đại
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
public class FileWrapper : IDisposable
{
private SafeFileHandle _handle;
public FileWrapper(string path)
{
_handle = File.OpenHandle(path); // SafeHandle tự manage lifetime
}
public void Dispose()
{
_handle?.Dispose(); // Không cần finalizer thủ công
}
}
Tóm tắt
| Câu hỏi | Trả lời |
|---|---|
| Số lượng destructor tối đa? | 1 |
| Có tham số không? | Không |
| Có access modifier không? | Không |
| Trong struct được không? | Không |
| Gọi được thủ công không? | Không |
| Kế thừa được không? | Không (nhưng base.Finalize() được gọi tự động) |