在 C# 中,终结器(finalizer)是一种由垃圾回收器在回收对象内存之前自动调用的方法,主要用来释放对象持有的非托管资源。C# 并没有直接提供名为 finalizer 的关键字,而是用析构函数的语法来定义它,编译器会将该语法转换为标准的终结器。

终结器的语法形式
在类中使用波浪号加类名即可声明一个终结器,它不接受参数也没有返回值,也不能被显式调用或重载:
using System;
class Sample
{
// 这就是 C# 中的析构函数,会被编译为终结器
~Sample()
{
// 释放非托管资源的逻辑
Console.WriteLine("Sample 对象被终结");
}
}
终结器和析构函数的关系
C# 里的析构函数只是语法糖。编译后,上面的 ~Sample() 会生成一个名为 Finalize 的受保护重写方法。因此可以说,C# 的析构函数本质上就是终结器,二者指向同一机制。
编译后的等价结构
protected override void Finalize()
{
try
{
// 用户编写的析构函数体
Console.WriteLine("Sample 对象被终结");
}
finally
{
base.Finalize();
}
}
使用终结器的注意事项
- 终结器只适合释放非托管资源,托管资源交给垃圾回收器即可。
- 有终结器的对象会被放入终结队列,延长存活时间,影响性能。
- 若已实现 IDisposable 模式,应在 Dispose 中调用 GC.SuppressFinalize 来避免重复释放。
结合 Dispose 模式的推荐写法
using System;
class ResourceHolder : IDisposable
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// 释放托管资源
}
// 释放非托管资源
disposed = true;
}
}
~ResourceHolder()
{
Dispose(false);
}
}
小结
终结器是 C# 在垃圾回收阶段清理非托管资源的保障机制,开发者写出的析构函数就是它的表层写法。实际项目中,更推荐配合 IDisposable 接口使用,既保证资源及时释放,也减少终结器带来的性能开销。