我总是会搞混这些东西,还是写下来帮助记忆。

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
posted on 2008-04-16 15:46  Yao Min  阅读(548)  评论(0编辑  收藏  举报