C# essential 2.0 Resources Cleanup中有这么一句话
the garbage collector is responsible for calling a finalizer on an object instance.
垃圾回收器负责为一个对象调用终结器。

然而又有这么一句
The runtime cannot garbage collect objects with finalizers until after their finalization methods have been called. However, garbage collection itself does not call the finalization method. Rather, references to finalization objects are added to the f-reachable queue, thereby ironically delaying garbage collection.
如果一个对象有些终结器,那么运行时只要在终结方法被调用后才对其执行垃圾回收。然而垃圾回收本身不调用终结方法,而将具有终结方法的对象的应用添加到f-reachable队列中,从而事实上推迟了垃圾回收。

finalizer终结器 相当于C++中的析构函数,无返回值无参数从而无法重载。width finalizers,说明有多个终结器,这很让人疑惑啊?

如果紧扣字面意思,finalizer 和finalization method不是同一个概念。此时“垃圾回收器负责为一个对象调用终结器。”和“垃圾回收本身不调用终结方法,”之间没有冲突。反之则有冲突。

finalizer 指类似C++中析构函数语法一样的一个类最多只能有一个的函数。由于垃圾回收只是完成对对象占用的内存的回收,而垃圾回收是不需要依赖这样一个函数的。所以它实际上式没有什么用处的,除非你希望让垃圾回收器通过对终结器的调用完成对非内存资源的自动回收,此时应该在终结器中加入释放非内存资源的代码。但是这样做必须确保一个条件,即这些非内存资源的释放次序和释放时机不会带来任何问题;当然这个条件在99.99%的情况下是无法满足的,从而终结器还是没什么用处的。
finalization method 特指实现了IDispose接口的类的Dispose方法和为了符合程序员调用习惯而实现的和Dispose具有相同功能的Close(用于关联文件的类)、Disconnect(用于连接数据库的类)等方法。这些方法用来实现对对象占用的非内存资源进行回收。

“而垃圾回收是不需要依赖这样一个函数的”这句话,需要进一步说明一下。
它是说在表面上看起来不依赖像C++中析构函数一样的函数。实际上是否依赖由具体的实现确定。如果垃圾回收按方法是:如果没有为一个类提供终结器,在编译器为其添加一个终结器,在终结器中调用垃圾回收的内存管理方法完成对内存的释放;如果为一个类提供了终结器,就在终结器的返回语句之前,编码者提供的语句之后添加实现垃圾回收的语句。就会依赖终结器。
如果实现方法是:通过一个对象的引用获取此对象在内存中的起始位置和占用内存的大小然后由垃圾回收器完成对其的回收。就不依赖终结器。

关于finalization method 终结方法也需要进一步说明一下。一般情况下它特指实现了IDispose接口的类的Dispose方法,实现接口的这个方法是为了using语句的实现。实现这个接口还向类的用户透露了另外一个信息,就是这类占用了非内存资源,不能依赖垃圾回收机制完成这些非内存资源的释放。这个接口的实现也为垃圾回收器透露了一个信息,垃圾回收器对内存的回收必须发生在Dispose方法调用之后;并且垃圾回收器不应该再调用终结器(类似C++析构函数的函数)了,如果内存资源的回收不依赖终结器。对于微软的实现来说其实是指向此对象的存在于垃圾回收线程里f-reachable队列中的唯一一个引用被从这个队列中移除之后执行内存资源回收。垃圾回收具有当终结方法被调用后从f-reachable队列中移除这个引用的功能。这个功能需要我们显式的在终结方法(Dispose)的最后调用,它是System.GC.SuppressFinalize(this)。如果垃圾的回收依赖终结器且在终结器中加入了释放非内存资源的代码此时会出现矛盾;因为如果垃圾回收依赖终结器则任何时候都不应该阻止终结器的调用,而终结方法中也包含了对非内存资源的释放;对同一个资源释放两次不是好事,虽然可以通过一个布尔标记来解决冲突。

当然Dispose也可由编码者直接调用,但是如果方法的声明能够做到见名知意则更好。所以对已关联到文件的类实现一个符合习惯的名称为Close的方法来完成和Dispose一样的功能,为连接到数据库的类实现一个符合习惯的名称为Disconnect的方法。

以上是从C# essential 2.0 中总结出的信息。但是这个信息和从programing C#中得出的信息存在矛盾。参见下面两个网址(列出了其关键信息)
http://hi.baidu.com/linxing_wang/blog/item/0561f31f7bd818c0a786692f.html

Dispose()方法调用Dispose(true),而GC调用的是Dispose(false)。这有什么区别呢?讲清楚这个问题,我们需要将非托管资源分成两类(这些是我自己的说法,可能会有bug哦^_^),一类是只被一个对象享用的非托管资源,在上例中以buffer表示。另一类是被许多对象享用的非托管资源,在上例中以resouce表示。自己独享的资源当此对象销亡时必须释放,所以在GC调用时会考虑释放该资源。但另一类被共享的资源则不能由GC来释放,因为GC释放次序是不定的,无法确认释放这个资源后是否有其他对象在使用该资源。而了解这个的,只有调用者自己。因此只能依赖于调用者自己手动调用Dispose()或Close()来释放该资源。也就是说,手动的调用,会释放该对象使用的所有非托管资源,而自动调用只能释放该对象独享的非托管资源。

http://blog.sina.com.cn/s/blog_4a99b1ba010005kg.html

       
System.GC.SuppressFinalize(this);//手动调用了Dispose释放资源,那么析构函数就是不必要的了,这里阻止GC调用析构函数


鉴于这些复杂的机制与模糊的描述,几乎80%以上使用C#的程序员仍然无法编写出安全的代码。

其实我想外国人都是傻逼,利用中国人的智慧提升了自己的声誉而已。看看他们创造的语言吧都是乱七八糟,没有一门好用的。最好的语言将会出现在中国。
但是有德行的外国人还是会承认他们从利用了中国人的智慧。比如计算机的创始人冯.洛裔曼就承认计算机发源于《易经》,因为道生一,一生二,二生三,三生万物。
计算机就用一个电子元件(一)的两个状态(高低电位,即二)就表示了世间的万物。