C# 中的析构函数

2025 年 8 月 28 日 | 阅读 6 分钟

在 C# 编程语言中,析构函数是一种在类中定义的特殊方法,用于在对象被从内存中移除之前执行清理操作。一个程序中的一个类只能包含一个析构函数。它以波浪号 (~) 符号后跟类名作为前缀。

析构函数在对象被垃圾回收器 (GC) 回收之前自动调用。它们主要用于释放非托管资源(如文件句柄、数据库连接、网络套接字等)。

由于 .NET 垃圾回收器会自动管理托管对象的内存,因此当类与文件、数据库连接和本机句柄等资源进行交互时,析构函数会很有帮助。

语法

它具有以下语法:

在此语法中;

  • class class_name: 用于定义类名。
  • ~class_name: 用于定义析构函数。

C# 析构函数示例

让我们以一个例子来说明 C# 中的析构函数。

示例

编译并运行

输出

An instance of Tpointtech class is created.
An instance of Tpointtech class is destroyed.

说明

在此示例中,我们使用了一个类构造函数。当我们创建 Tpointtech 类的对象时,构造函数会执行并显示一条消息。将对象设置为 null 后,使用 GC.Collect() 和 GC.WaitForPendingFinalizers() 函数强制运行垃圾回收器,这将调用析构函数。之后,析构函数会自动运行,在对象被销毁之前执行清理任务。

析构函数的主要特征

C# 编程语言中的析构函数有以下几个主要特征:

  • 析构函数不能带参数,也没有返回值。
  • 它没有访问修饰符(public、private 等)。
  • 每个类只允许一个析构函数。
  • 它不能手动调用。它由垃圾回收器自动执行。
  • 我们只能在类中定义析构函数,而不能在结构体 (structs) 中定义。
  • 我们不能继承或重载析构函数。

带文件处理的 C# 析构函数示例

让我们以一个例子来说明 C# 中带文件处理的析构函数。

示例

编译并运行

输出

File opened successfully.
Working with file...
File closed successfully.

说明

在此示例中,我们创建了一个名为 File_hand 的类,其构造函数在创建对象时打开一个文件。析构函数可确保在垃圾回收器销毁对象时文件被成功关闭。通过在不再需要文件句柄时自动释放它,确保了安全的资源管理。

C# 中的析构函数如何与垃圾回收器协同工作?

C# 使用非确定性垃圾回收系统,这意味着我们无法准确预测垃圾回收器何时执行或何时调用析构函数。运行时根据可用资源和内存压力决定何时是清理内存的好时机。

何时在 C# 中使用析构函数?

在 C# 编程中,当一个类执行多项涉及非托管资源(如数据库连接、网络套接字、文件处理等)的任务时,应使用析构函数。析构函数的主要用途是作为一种清理机制,以确保在对象被销毁之前正确释放非托管资源。

C# 析构函数还可以作为备份安全网,以防 Dispose() 方法未被显式调用。此外,当我们在处理非托管资源时,析构函数也很有用,并且 IDisposable 接口及其 Dispose() 方法适用于清理资源。如果我们正在处理与本机库或 API 交互的互操作代码,那么它将非常有用。

C# 中的 IDisposable 和 Dispose 模式

让我们以一个例子来说明 C# 中的 IDisposable 和 Dispose 模式。

示例

编译并运行

输出

File Opened
Working with file
File Closed

说明

在此示例中,我们使用了 file_handle 类,该类在其构造函数中打开一个文件,并通过 Dispose() 方法确保清理,该方法在 using 块结束时自动调用。之后,Dispose(bool disposing) 方法会释放托管和非托管资源,而析构函数在 Dispose() 方法未被显式调用时充当安全网。

C# 中的析构函数和 Finalize 方法

在 C# 编程语言中,析构函数和 Finalize() 方法主要用于资源清理,但它们在几个方面有所不同。C# 中的析构函数本质上是 .NET 运行时提供的 Finalize() 方法的语法包装器。如果我们使用 C# 编写析构函数,编译器会自动将其转换为对 Object.Finalize() 方法的重写。我们可以手动重写 Finalize(),但定义析构函数是更简单、更安全的选择。

语法

它具有以下语法:

C# 析构函数和 Finalize 方法示例

让我们以一个例子来说明 C# 中的析构函数和 finalize 方法。

示例

编译并运行

输出

main.cs(10,29): error CS0249: Do not override `object.Finalize()'. Use destructor syntax instead

说明

在此示例中,我们使用了 Tpoint 类,然后使用一个构造函数来创建对象,而 Finalize() 方法由垃圾回收器自动调用,在对象销毁前清理资源。最后,通过使用 GC.Collect() 和 GC.WaitForPendingFinalizers() 方法强制执行垃圾回收,程序确保 Finalize() 方法在 main 方法结束前执行。

C# 中的构造函数和析构函数之间的区别

C# 中的构造函数和析构函数之间存在一些区别。其中一些如下:

特点构造函数析构函数
目的它在创建对象时初始化对象。它在销毁对象之前执行清理操作。
调用在对象创建期间显式调用它。当对象被销毁时,垃圾回收器会自动调用它。
资源分配它用于资源分配。它常用于资源去分配。
参数化它可以接受参数进行自定义初始化。它不允许任何参数。
实例可以定义具有不同参数的多个构造函数。一个类只包含一个析构函数,不包含任何重载。

结论

总之,C# 析构函数提供了一种在对象被销毁前进行清理的技术。当对象变得不可达时,垃圾回收器会自动调用它们。它们在特定场景下很有用,例如处理非托管资源或与本机代码交互。在现代 C# 编程中,最好使用 IDisposable 并实现 Dispose() 模式以获得更可预测、更高效的资源管理。

C# 析构函数常见问题解答

1. C# 中的析构函数是什么?

在 C# 编程语言中,析构函数是一种在对象被销毁之前由垃圾回收器自动调用的方法。它主要用于释放非托管资源。

2. C# 中的析构函数何时被调用?

在 C# 中,析构函数由垃圾回收器 (GC) 在不确定的时间自动调用。

3. 我们可以在 C# 中显式调用析构函数吗?

不,我们不能直接在 C# 中调用析构函数。它由垃圾回收器 (GC) 调用。

4. C# 中的结构体可以有析构函数吗?

不,结构体在 C# 中不能包含析构函数。结构体是值类型,而析构函数只能用于引用类型。

5. C# 中的析构函数可以被重写吗?

不,析构函数不能在 C# 中被重写。每个类都可以有自己的析构函数。


下一主题C# this