终结器(C# 编程指南)Finalizers (C# Programming Guide)

终结器(也称为 析构函数)用于在垃圾回收器收集类实例时执行任何必要的最终清理操作。Finalizers (which are also called destructors) are used to perform any necessary final clean-up when a class instance is being collected by the garbage collector.

备注Remarks

  • 无法在结构中定义终结器。Finalizers cannot be defined in structs. 它们仅用于类。They are only used with classes.

  • 一个类只能有一个终结器。A class can only have one finalizer.

  • 不能继承或重载终结器。Finalizers cannot be inherited or overloaded.

  • 不能手动调用终结器。Finalizers cannot be called. 可以自动调用它们。They are invoked automatically.

  • 终结器不使用修饰符或参数。A finalizer does not take modifiers or have parameters.

例如,以下是类 Car 的终结器声明。For example, the following is a declaration of a finalizer for the Car class.

class Car
{
    ~Car()  // finalizer
    {
        // cleanup statements...
    }
}

终结器也可以作为表达式主体定义实现,如下面的示例所示。A finalizer can also be implemented as an expression body definition, as the following example shows.

using System;

public class Destroyer
{
   public override string ToString() => GetType().Name;
   
   ~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");
}

终结器隐式调用对象基类上的 FinalizeThe finalizer implicitly calls Finalize on the base class of the object. 因此,对终结器的调用会隐式转换为以下代码:Therefore, a call to a finalizer is implicitly translated to the following code:

protected override void Finalize()  
{  
    try  
    {  
        // Cleanup statements...  
    }  
    finally  
    {  
        base.Finalize();  
    }  
}  

这意味着,对继承链(从派生程度最高到派生程度最低)中的所有实例以递归方式调用 Finalize 方法。This means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.

备注

不应使用空终结器。Empty finalizers should not be used. 如果类包含终结器,会在 Finalize 队列中创建一个条目。When a class contains a finalizer, an entry is created in the Finalize queue. 调用终结器时,会调用垃圾回收器来处理该队列。When the finalizer is called, the garbage collector is invoked to process the queue. 空终结器只会导致不必要的性能损失。An empty finalizer just causes a needless loss of performance.

程序员无法控制何时调用终结器,因为这由垃圾回收器决定。The programmer has no control over when the finalizer is called because this is determined by the garbage collector. 垃圾回收器检查应用程序不再使用的对象。The garbage collector checks for objects that are no longer being used by the application. 如果它认为某个对象符合终止条件,则调用终结器(如果有),并回收用来存储此对象的内存。If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object.

在 .NET Framework 应用程序中(但不在 .NET Core 应用程序中),程序退出时也会调用终结器。In .NET Framework applications (but not in .NET Core applications), finalizers are also called when the program exits.

可以通过调用 Collect 强制进行垃圾回收,但多数情况下应避免此操作,因为它可能会造成性能问题。It is possible to force garbage collection by calling Collect, but most of the time, this should be avoided because it may create performance issues.

使用终结器释放资源Using finalizers to release resources

一般来说,C# 所占用的内存管理空间比使用不面向带有垃圾回收机制的运行时的语言进行开发时所使用的内存管理空间要少。In general, C# does not require as much memory management as is needed when you develop with a language that does not target a runtime with garbage collection. 这是因为 .NET Framework 垃圾回收器会隐式管理对象的内存分配和释放。This is because the .NET Framework garbage collector implicitly manages the allocation and release of memory for your objects. 但是,如果应用程序封装非托管的资源,例如窗口、文件和网络连接,则应使用终结器释放这些资源。However, when your application encapsulates unmanaged resources such as windows, files, and network connections, you should use finalizers to free those resources. 当对象符合终止条件时,垃圾回收器会运行对象的 Finalize 方法。When the object is eligible for finalization, the garbage collector runs the Finalize method of the object.

显式释放资源Explicit release of resources

如果应用程序正在使用昂贵的外部资源,我们还建议在垃圾回收器释放对象前显式释放资源。If your application is using an expensive external resource, we also recommend that you provide a way to explicitly release the resource before the garbage collector frees the object. 若要实现此操作,可从执行必要的对象清除的 IDisposable 接口实现 Dispose 方法。You do this by implementing a Dispose method from the IDisposable interface that performs the necessary cleanup for the object. 这样可大大提高应用程序的性能。This can considerably improve the performance of the application. 如果调用 Dispose 方法失败,那么即使拥有对资源的显式控制,终结器也会成为清除资源的一个保障。Even with this explicit control over resources, the finalizer becomes a safeguard to clean up resources if the call to the Dispose method failed.

有关清除资源的详细信息,请参阅下列主题:For more details about cleaning up resources, see the following topics:

示例Example

以下示例创建了三个类,并且这三个类构成了一个继承链。The following example creates three classes that make a chain of inheritance. First 是基类,Second 派生自 FirstThird 派生自 SecondThe class First is the base class, Second is derived from First, and Third is derived from Second. 这三个类都具有终结器。All three have finalizers. Main 中,已创建派生程度最高的类的一个实例。In Main, an instance of the most-derived class is created. 程序运行时,请注意,将按顺序(从派生程度最高到派生程度最低)自动调用这三个类的终结器。When the program runs, notice that the finalizers for the three classes are called automatically, and in order, from the most-derived to the least-derived.

class First
{
    ~First()
    {
        System.Diagnostics.Trace.WriteLine("First's destructor is called.");
    }
}

class Second : First
{
    ~Second()
    {
        System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
    }
}

class Third : Second
{
    ~Third()
    {
        System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
    }
}

class TestDestructors
{
    static void Main()
    {
        Third t = new Third();
    }

}
/* Output (to VS Output Window):
    Third's destructor is called.
    Second's destructor is called.
    First's destructor is called.
*/

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范中的析构函数部分。For more information, see the Destructors section of the C# language specification.

请参阅See also