Finalize/Dispose/Destructor
我总是会搞混这些东西,还是写下来帮助记忆。
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里精辟的例子。
// 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 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 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
Finalize/Dispose/Destructor相关推荐
- Finalize,Dispose,SuppressFinalize
MSDN建议按照下面的模式实现IDisposable接口: Code1 public class Foo: IDisposable2 {3 public void Dispose()4 {5 Disp ...
- dispose 模式 java_C#使用Dispose模式实现手动对资源的释放
本文实例讲述了C#使用Dispose模式实现手动对资源的释放.分享给大家供大家参考.具体实现方法如下: //单一类的实现 class MyClass : IDisposable { public My ...
- C#垃圾回收学习总结
浅谈C#垃圾回收 http://www.cnblogs.com/cuiyiming/archive/2013/03/26/2981931.html 理解C#垃圾回收机制我们首先说一下CLR(公共语言运 ...
- C++编程人员容易犯的10个C#错误
C++编程人员容易犯的10个C#错误 C#的语法与C++非常相似,有些变化引起的错误却很严重,本讨论C++编程人员最容易犯的十个错误. 我们知道,C#的语法与C++非常相似,实现从C++向C#的转变, ...
- 面向对象——垃圾回收
一.垃圾回收 托管堆的工作方式非常类似于栈,在某种程度上,对象子内存中一个挨一个地放置,这样很容易指向下一个空间存储单元的堆指针,来确定下一个对象的位置. 在垃圾回收器运行时,它会从堆中删除不再引用 ...
- java注释风格 与javadoc
javadoc做注释 一. Java 文档 // 注释一行 /* ...... */ 注释若干行 /** ...... */ 注释若干行,并写入 javadoc 文档 通常这种注释的多行写法如下 ...
- 如何写Java文档注释(Java Doc Comments)
本文翻译自How to Write Doc Comments for the Javadoc Tool,但是精简了一些私以为不重要的东西 本文不讨论如何使用javadoc工具自动生成文档的方法,而是主 ...
- java文档注释 编写格式
java 文档注释 在sun主页上有java文档注释的编写格式 How to Write Doc Comments for the Javadoc Tool http://java.sun.com/j ...
- 【转】C#的内存管理:堆栈、托管堆与指针
在32位的Windows操作系统中,每个进程都可以使用4GB的内存,这得益于虚拟寻址技术,在这4GB的内存中存储着可执行代码.代码加载的DLL和程序运行的所有变量,在C#中,虚拟内存中有个两个存储变量 ...
最新文章
- 大众点评字体_点评里的神笔马良!她的美食笔记会让你惊掉下巴!
- SAP系统中设备管理模块的主要增强出口
- pythonseleniumAPI
- 手把手实现YOLOv3(二)
- Java,JavaFX的流畅设计风格拨动开关
- Linux移植随笔:让内核支持nor flash
- Use Namesapce 使用方法简介
- Java collection 集合类架构
- 腾讯云服务器ftp部署及文件上传
- java判断是否为5的倍数,如何用编程实现“判断输入的正整数是否既是5又是7的正倍数,若是,则输出yes,否则输出no”?...
- win7添加java环境变量path_Win7怎么配置Java环境变量?
- HTML5 通过Vedio标签实现视频循环播放
- 【笔记本触摸屏】实用技巧整理
- vue实现非同源图片的下载功能--跨域问题(解决浏览器打开图片,而不是下载)
- mstar v56几路hdmi_MSTAR运用及问题汇总_整理
- 《途客圈创业记:不疯魔,不成活》一一2.5 完善拼图
- [单片机][FUSB302][PD1.0][PD2.0] PD协议 Demo 例子 代码
- Facebook或面临2000000000000美元罚款,扎克伯格认错
- 计算机可以查到刻录光盘的记录,光盘刻录信息记录在什么位置上
- windows的命令行(CMD)
热门文章
- php JSON数据格式化输出方法
- 在SQLserver数据库里设置作业的步骤
- SAP BADI应用
- ActiveMQ在C#中的应用
- OpenCV 【十八】图像平滑处理/腐蚀与膨胀(Eroding and Dilating)/开闭运算,形态梯度,顶帽,黑帽运算
- 三维重建【三】-------------------(三维重建资料收集)
- JDK源码分析 NIO实现
- Linux0.01内核根目录Makefile注释
- 超强的jquery极品插件--色彩选择器类/ 右键菜单类/ 图片新闻flash展示类
- gridview列 数字、货币和日期 显示格式