我总是会搞混这些东西,还是写下来帮助记忆。
Finalize 即Object.Finalize(),C#中不允许使用Finalize,析构器就等价于Finalize。 Destructor 析构器(Destructor)是在对象没有被引用的时候,由CLR自动调用的。 任何包含非托管资源的类都必须定义析构器来释放这些资源,因为它们并不会在对象消亡时自动释放,而托管资源就可以。 Dispose方法 Dispose方法是IDisposable接口的实现方法,Dispose方法并不会被自动调用。 这里还有Dispose(bool)方法的概念,由于类的使用者或许会忘记使用Dispose()方法,并且析构器有可能二次执行析构操作,所以设计Dispose(bool)重载方法来判断并释放托管资源。合理的设计思想是,在Dispose()中使用Dispose(true)来显式释放托管资源和非托管资源,而在析构器中使用Dispose(false),只释放非托管资源(CLR会去自动调用托管资源的析构器)。在Dispose()方法中应使用GC.GC.SuppressFinalize()方法来阻止CLR调用析构器。 至于Close()方法,只是一种习惯名称,一般直接调用Dispose()方法。 来看MSDN里精辟的例子。 // Design pattern for the base class. // By implementing IDisposable, you are announcing that instances // of this type allocate scarce resources. public class BaseResource: IDisposable { // Pointer to an external unmanaged resource. private IntPtr handle; // Other managed resource this class uses. private Component Components; // Track whether Dispose has been called. private bool disposed = false ; // Constructor for the BaseResource object. public BaseResource() { // Insert appropriate constructor code here. } // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose( true ); // Take yourself off the Finalization queue // to prevent finalization code for this object // from executing a second time. GC.SuppressFinalize( this ); } // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. protected virtual void Dispose( bool disposing) { // Check to see if Dispose has already been called. if ( ! this .disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if (disposing) { // Dispose managed resources. Components.Dispose(); } // Release unmanaged resources. If disposing is false, // only the following code is executed. CloseHandle(handle); handle = IntPtr.Zero; // Note that this is not thread safe. // Another thread could start disposing the object // after the managed resources are disposed, // but before the disposed flag is set to true. // If thread safety is necessary, it must be // implemented by the client. } disposed = true ; } // Use C# destructor syntax for finalization code. // This destructor will run only if the Dispose method // does not get called. // It gives your base class the opportunity to finalize. // Do not provide destructors in types derived from this class. ~ BaseResource() { // Do not re-create Dispose clean-up code here. // Calling Dispose(false) is optimal in terms of // readability and maintainability. Dispose( false ); } // Allow your Dispose method to be called multiple times, // but throw an exception if the object has been disposed. // Whenever you do something with this class, // check to see if it has been disposed. public void DoSomething() { if ( this .disposed) { throw new ObjectDisposedException(); } } } // Design pattern for a derived class. // Note that this derived class inherently implements the // IDisposable interface because it is implemented in the base class. public class MyResourceWrapper: BaseResource { // A managed resource that you add in this derived class. private ManagedResource addedManaged; // A native unmanaged resource that you add in this derived class. private NativeResource addedNative; private bool disposed = false ; // Constructor for this object. public MyResourceWrapper() { // Insert appropriate constructor code here. } protected override void Dispose( bool disposing) { if ( ! this .disposed) { try { if (disposing) { // Release the managed resources you added in // this derived class here. addedManaged.Dispose(); } // Release the native unmanaged resources you added // in this derived class here. CloseHandle(addedNative); this .disposed = true ; } finally { // Call Dispose on your base class. base .Dispose(disposing); } } } } // This derived class does not have a Finalize method // or a Dispose method without parameters because it inherits // them from the base class.
有一个热传的对象复活(resurrection)的例子
public class Resurrection { public int Data; public Resurrection( int data) { Data = data; } ~ Resurrection() { Main.Instance = this ; } } public class Main { public static Resurrection Instance; public static void Main() { Instance = new Resurrection( 1 ); Instance = null ; GC.Collect(); GC.WaitForPendingFinalizers(); // 看到了吗,在这里“复活”了。 Console.WriteLine(Instance.Data); Instance = null ; GC.Collect(); Console.ReadLine(); } }
还有一个弱引用的例子,弱引用的对象在回收以前还是可以被重复使用的。 public class Fat { public int Data; public Fat( int data) { Data = data; } } public class MainClass { public static void Main() { Fat oFat = new Fat( 1 ); WeakReference oFatRef = new WeakReference(oFat); // 从这里开始,Fat对象可以被回收了。 oFat = null ; if (oFatRef.IsAlive) { Console.WriteLine(((Fat) oFatRef.Target).Data); } GC.Collect(); Console.WriteLine(oFatRef.IsAlive); // False Console.ReadLine(); } }
参考: http://msdn2.microsoft.com/zh-cn/library/fs2xkftw(VS.80).aspx http://blog.csdn.net/sykpboy/archive/2005/04/11/342971.aspx