C#基础 [11] 析构函数

一、析构函数

  析构函数(destructor)用于析构类的实例。即在类的实例被销毁之前,执行资源的清理或者释放非托管资源。下面的代码示例中声明了一个名为Car的类,该类包含一个名为~Car的析构函数:

1     class Car
2     {
3         ~Car()  // destructor
4         {
5             // 执行清理
6         }
7     }

  析构函数的特征如下:

    1.不能在结构中定义析构函数。只能对类使用析构函数。

    2.每个类只能有一个析构函数。

    3.析构函数名为:"~"+类名,比如~Car。

    4.析构函数不能带访问修饰符。

    5.析构函数不能带参数,自然也无法重载。

    6.析构函数是用来析构类的实例的,因此没有静态析构函数。

    7.不能显式调用析构函数。析构函数是在垃圾收集过程中被自动调用的:如果垃圾回收器认为某个对象符合析构,则调用析构函数(如果有)并回收用来存储此对象的内存。程序退出时也会调用析构函数。

    8.该析构函数隐式地对对象的基类调用 Finalize。反编译上例的类Car,得到下面的结果:

1 internal class Car
2 {
3     // Methods
4     public Car();
5     protected override void Finalize();
6 }

  该代码包括一个构造函数和一个重写的Finalze方法,其实这就是构造函数编译之后的代码。

  下面是另外一个析构函数的示例:下面的示例创建三个类,这三个类构成了一个继承链。First 是基类,Second 是从 First 派生的,而 Third 是从 Second 派生的。这三个类都有析构函数。Main() 中,创建了派生程度最大的类的实例。注意:程序运行时,这三个类的析构函数将自动被调用,并且是按照从派生程度最大的到派生程度最小的次序调用。

View Code
 1     class First
 2     {
 3         ~First()
 4         {
 5             System.Diagnostics.Trace.WriteLine("First's destructor is called.");
 6         }
 7     }
 8 
 9     class Second : First
10     {
11         ~Second()
12         {
13             System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
14         }
15     }
16 
17     class Third : Second
18     {
19         ~Third()
20         {
21             System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
22         }
23     }
24 
25     class Program
26     {
27         static void Main(string[] args)
28         {
29             Third t = new Third();
30 
31             /* 输出结果 (在 VS 的输出窗口中可以看到):
32             Third's destructor is called.
33             Second's destructor is called.
34             First's destructor is called.
35             */
36         }
37     }

二、何时使用析构函数?

  通常,与运行时不进行垃圾回收的开发语言相比,C# 无需太多的内存管理。这是因为 .NET Framework 垃圾回收器会隐式地管理对象的内存分配和释放。但是,当应用程序封装窗口、文件和网络连接这类非托管资源时,应当使用析构函数释放这些资源。当对象符合析构时,垃圾回收器将运行对象的 Finalize 方法。

三、显式释放资源

  如果代码中包含了需要及时释放的非托管资源,就不能使用析构函数实现,因为析构函数不能显式调用,我们不能确定它什么时候才能被GC调用,所以是不可控制的。对于这种情况,我们可以实现IDisposable接口。只要类实现了IDisposable即可,就可以调用它的Dispose方法来释放非托管资源。关于IDisposable接口和资源释放的更多内容,我会在以后的文章中继续研究。 

  参考:http://msdn.microsoft.com/zh-cn/library/66x5fx1b(VS.100).aspx

 

posted @ 2013-01-02 19:10  YunshiSun  阅读(778)  评论(1编辑  收藏  举报