C#析构函数和dispose模式
析构函数
类可以⽤⽤析构函数(destructor),它可以在⼀个类的实例不在被引⽤的时候执⾏⼀些操作,以清除或释放⾮托管资源。⾮托管资源是指类似⽤Win32 API或⾮托管内存块获取的⽂件句柄这样的资源。使⽤.NET资源是⽆法获取它们的,因此如果我们只⽤.NET类。是不需要编写太多的析构函数的。
关于析构函数要注意以下⼏点。
·每个类只能有⼀个析构函数。
·析构函数不能有参数。
·析构函数不能有访问修饰符。
·析构函数名称与类名相同,但是前⾯加⼀个波浪符。
·析构函数只能作⽤于类的实例。因此没有静态的析构函数。
·不能再代码中显⽰调⽤析构函数。相反,当垃圾回收器分析代码并认为代码中不存在指向对象的可能路
径时,系统会在垃圾回收中调⽤析构函数。
使⽤析构函数是⼀些重要的原则如下:
·不要在不需要时实现析构函数。这会严重影响性能;
·析构函数应该只释放对象拥有的外部资源。
·析构函数不应该访问其他对象,因为⽆法认定这些对象是否已经被销毁。
标准dispose模式
标准dispose模式包含以下特点。
·包含⾮托管资源的类应该事先IDisposable接⼝,后者包含单⼀⽅法Dispose。Dispose包含释放资源的清除代码。
·如果代码使⽤完了这些资源且希望将他们释放,应该在程序代码中调⽤Dispose⽅法。注意,这是在你的代码中调⽤Dispose。
·你都累还应该实现⼀个析构函数,在其中调⽤Dispose⽅法,以防⽌之前没有调⽤该⽅法。你想讲所
有的清除代码放到Dispose中,并在使⽤完资源时调⽤。以防⽌Dispose没有调⽤,类的析构函数也应该调⽤Dispose。⽽另⼀⽅⾯如果调⽤了Dispose,你就希望通知垃圾回收器不要在调⽤析构函数,因为已经由Dispose执⾏了清除操作。
析构函数和Dispose代码应该遵循以下原则。
·修改函数和Dispose⽅法的逻辑应该是,如果由于某种原因代码没有调⽤Dispose,那么修改函数应该调⽤它,并释放资源。
·在Dispose⽅法的最后应该调⽤GC.SuppressFinalize⽅法,通知CLR不要电泳该对象的析构函数,因为清除⼯作已经完成。
·在Dispose中实现这些代码。这样多次调⽤该⽅法是安全的。也就是说代码要这样写:如果该⽅法已经被调⽤,那么任何后续调⽤都不回执⾏额外的⼯作,也不会抛出任何异常。
标准Dispose模式,要点:
·Dispose⽅法有两个重载:⼀个是public的,⼀个protected的。protected的重载包含实际的清除代码。
·public 版本可以在代码中显⽰调⽤以执⾏清除⼯作。它会调⽤protected版本。
·析构函数调⽤protected版本、
`protected版本的bool参数通知⽅法是被析构函数或是其他代码调⽤。这⼀点很重要,因为结果不同所执⾏的操作略有不同。
案例
class Class1 : IDisposable
{
bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Class1()
{
Console.WriteLine("析构函数释放了");
Dispose(false);
}
protected virtual void Dispose(bool disposing) {
if (disposed == false)
{
if (disposed == true)
{
//由Dispose是释放
}
writeline函数else if (disposed == false)
{
//由析构函数释放
}
disposed = true;
}
}
static void Main(string[] args) {
Class1 c = new Class1();
Console.ReadKey();
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论