在垃圾回收器销毁对象之前, 程序自动调用析构函数。
注意: 在讨论C#中的析构函数时, 在底层的.net 体系结构中,这些函数称为终结器。 在 C#中定义析构函数时, 编译器会发送给程序集的实际上是 Finalize() 方法。
先定义一个析构函数的类:
class MyClass
{
~MyClass()
{
}
}
析构定义规则:
- 前缀必须加~
- 没有返回类型
- 不带参数
- 没有访问修饰符
C#编译器在编译析构函数时,它会隐式地把析构函数的代码编译为等价于 Finalize() 方法的代码,从而确保执行父类的 Finalize()方法。 下面列出编译的等价代码:
protected override void Finalize()
{
try
{
// Finalizer implementation
}
finally
{
base.Finalize();
}
}
如上所示, 在 ~MyClass() 析构函数中实现的代码封装在 Finalize() 方法的一个 try 快中。 对父类的 Finalize 方法调用放在 finally块中, 确保该调用的执行。
对于C#在来说析构函数很少使用,因为C#的垃圾回收工作机制,导致无法确定C#对象的析构函数会在什么时候执行。所以不能在析构函数中放置需要在某一时刻运行的代码,也不要寄望于析构函数会以特定顺序对不同类的实例调用。如果对象占用了宝贵而重要的资源,应尽快释放这些资源,此时就不能等待垃圾回收器来释放了。
另一个问题是 C# 析构函数的实现会延迟对象最终从内存中删除的时间。 没有析构函数的对象会在垃圾回收器的一次处理中从内存中删除,但有析构函数的对象需要两次处理才能销毁: 第一次调用析构函数时,没有删除对象, 第二次调用才真正删除对象。 另外,运行库使用一个线程来执行所有对象的 Finalize 方法。如果频繁使用析构函数, 而且使用它们执行长时间的清理任务,对性能的影响就会非常显著。