博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Finalize/Dispose/Destructor
阅读量:6502 次
发布时间:2019-06-24

本文共 5405 字,大约阅读时间需要 18 分钟。

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

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

转载于:https://www.cnblogs.com/forck/archive/2008/04/16/1156343.html

你可能感兴趣的文章
device platform 相应的表
查看>>
php des 加密解密实例
查看>>
【Mac】Mac键盘实现Home, End, Page UP, Page DOWN
查看>>
实战使用Axure设计App,使用WebStorm开发(1) – 用Axure描述需求
查看>>
安德鲁斯----多媒体编程
查看>>
swift版的元组
查看>>
[zz]在linux中出现there are stopped jobs 的解决方法
查看>>
Delphi下实现全屏快速找图找色 一、数据提取
查看>>
查询表字段信息
查看>>
logback与Log4J的区别
查看>>
关于机器学习的最佳科普文章:《从机器学习谈起》
查看>>
咏南新CS三层开发框架
查看>>
dxFlowChart运行时调出编辑器
查看>>
TDiocpCoderTcpServer返回数据记录有条数限制的问题
查看>>
NET Framework 3.0 (WinFX) RTM发布
查看>>
图片拼接器
查看>>
C++ TinyXml操作(含源码下载)
查看>>
读取swf里所有类定义
查看>>
DOWNLOAD 文件
查看>>
黄聪:wordpress博客用Slimbox2实现lightbox效果(免插件)(转)
查看>>