在C#中,函数名称前的波浪号是什么意思?


164

我正在查看一些代码,它具有以下语句:

~ConnectionManager()
{
    Dispose(false);
}

该类实现了IDisposable接口,但是我不知道这是否是tilde(〜)用于的一部分。

Answers:


213

〜是析构函数

  1. 析构函数将自动调用,并且不能显式调用。
  2. 析构函数不能重载。因此,一个类最多可以具有一个析构函数。
  3. 析构函数不会被继承。因此,一个类除了可以在其中声明的析构函数外,没有其他析构函数。
  4. 析构函数不能与结构一起使用。它们仅与类一起使用。当不再有任何代码使用该实例时,该实例就可以销毁。
  5. 在实例符合销毁条件后的任何时候,都可以执行该实例的析构函数。
  6. 当实例被销毁时,其继承链中的析构函数按从最大派生到最小派生的顺序被调用。

完成

在C#中,Finalize方法执行标准C ++析构函数将执行的操作。在C#中,您没有将其命名为Finalize,而是使用C ++析构函数语法在类名之前放置一个波浪号(〜)符号。

处理

最好将对象放置在类的用户可以显式调用的Close()Dispose()方法中。Finalize(析构函数)由GC调用。

IDisposable的接口告诉世界,你的类保存到需要处置资源,并为用户提供一种方式来释放他们。如果确实需要在类中实现终结器,则Dispose方法使用该GC.SuppressFinalize()方法来确保实例的终结被抑制。

使用什么?

显式调用析构函数是非法的。您的析构函数将被垃圾收集器调用。如果确实要处理您想尽快关闭并处置的宝贵的非托管资源(例如文件句柄),则应实现IDisposable接口。


3
我不知道过去的样子。但是现在析构函数已被继承。检查此链接以获取更多信息(在末尾检查示例):msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex 2014年

1
您链接到该页面的@RononDex点3指出“无法继承Finalizers”,这与您的评论相矛盾。无疑,这有点令人困惑,因为尽管它们无法被继承,但Finalize对于继承链中从最高派生到最少派生的所有实例,该方法都是递归调用的”。请注意,这不是你的可继承析构函数得到的,但相同的行为。
Mark Amery

@MarkAmery啊,我知道了,所以与被继承的东西相比,它们基本上以相反的顺序被调用?
RononDex

45

这是终结器。老实说,您几乎不需要编写终结器。在以下情况下,您实际上只需要写一个:

  • 您可以直接访问非托管资源(例如,通过IntPtr),而不能使用SafeHandle它,这将使其变得更容易
  • 您正在IDisposable未密封的类中实现。(我倾向于密封类,除非它们是为继承而设计的。)在这种情况下,终结器是规范的Dispose模式的一部分。

9

用于指示类的析构函数。


12
它们都是正确的,具体取决于您阅读的C#规范。最新的MS版本(统一的C#3.0)将它们称为析构函数(例如10.13节),但ECMA规范将其称为终结器。
乔恩·斯基特

@ 1800INFORMATION:语法元素正确地称为析构函数。如果一个类具有析构函数,则C#编译器将自动生成一个终结器,该终结器包括一个通常无用的try/finally块,以确保Finalize调用父方法。析构函数中大多数正确的事物都适用于终结器,反之亦然,但是这些词的含义略有不同。
2014年



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.