Effective C# 标准析构模式的实现

来源:互联网 发布:雅马哈p电脑软件 编辑:程序博客网 时间:2024/05/22 10:42

标准的析构模式的实现要点如下:

 

  1. 每个使用非托管资源的类都应实现IDisposable接口

实现该接口的内部逻辑应包括以下几点

  1. 释放所有非托管资源
  2. 释放所有托管资源
  3. 设置一个标志位,说明该对象已被析构。当然还需要校验该对象的当前状态并在被其他调用时throw ObjectDisposedExption
  4. 调用GC.SuppressFinalize(this)来通知GC去释放

IDisposable就一个方法,其代码如下:

 

publicinterface IDisposable

{

voidDispose();

}

 

  1. 每个使用非托管资源的类都应实现finalizer

GC运行的时候,他会立即将没有finalizer的垃圾对象回收移除,剩下的对象会被放到到一个析构队列中,然后GC会创建一个新线程去调用队列中每个对象的finalizer

 

  1. 对于子类的析构,需重载其父类的Dispose方法,并在其方法中析构自己的托管和非托管对象,并且不要忘记调用父类的析构方法。

你可以在父类中,定义一个虚方法来定义负父类的析构方法代码如下:

// isDisposingfalse的时候只析构你的非托管资源,为true的时候析构所有托管及非托管资源

protectedvirtual void Dispose(bool isDisposing)

 

下面是一段完整的实现:

publicclass MyResourceHog : IDisposable

{

//Flag for already disposed

privatebool alreadyDisposed = false;

//Implementation of IDisposable.

//Call the virtual Dispose method.

//Suppress Finalization.

publicvoid Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

//Virtual Dispose method

protectedvirtual void Dispose(bool isDisposing)

{

//Don't dispose more than once.

if(alreadyDisposed)

return;

if(isDisposing)

{

//elided: free managed resources here.

}

//elided: free unmanaged resources here.

//Set disposed flag:

alreadyDisposed= true;

}

publicvoid ExampleMethod()

{

if(alreadyDisposed)

thrownew ObjectDisposedException(

"MyResourceHog",

"CalledExample Method on Disposed object");

//remainder elided.

}

}

//继承的类

publicclass DerivedResourceHog : MyResourceHog

{

//Have its own disposed flag.

privatebool disposed = false;

protectedoverride void Dispose(bool isDisposing)

{

//Don't dispose more than once.

if(disposed)

return;

if(isDisposing)

{

//TODO: free managed resources here.

}

//TODO: free unmanaged resources here.

//Let the base class free its resources.

//Base class is responsible for calling

//GC.SuppressFinalize( )

base.Dispose(isDisposing);

//Set derived class disposed flag:

disposed= true;

}

}

注意:这里子类和父类中都定义了是否已析构的标志位,这时为了保证该对象在各种类型的构造下都释放了资源。

 

  1. 不要在析构方法里添加与析构无关的代码,否则会引起严重的问题

原创粉丝点击