如何处理IDisposable?

雷米

假设我有这3个班级。

abstract class MyBase
{
    //some base code here
}

class Foo : MyBase, IDisposable
{
    //got at least a field I should dispose
}

class Bar : MyBase, IDisposable
{
    //got at least a field I should dispose
}

我有几个这样的课程。我的班级拥有List<base>我如何才能正确处理所有这些类,而不必进行测试/发布以获取正确的类型,然后再进行处理Dispose呢?

威科

如果可处置性是基类合同的一部分,为什么不明确说明呢?

abstract class MyBase : IDisposable
{
    //some base code here

    //an abstract "implementation" of the interface
    public abstract void Dispose();
}

这样,您可以确保其所有后代实际上都是可抛弃的。您还可以按照以下方式创建一个集合类,而不是一个通用列表:

class MyBaseCollection : IEnumerable<MyBase>
{
    private List<MyBase> innerCollection;
    ....
    public void DisposeItems()
    {
       // call Dispose on each item here
    }
}

正确处理非托管资源可能会非常棘手,并且会导致调试困难。在具体类上实现IDisposable接口时,应遵循Dispose模式

在抽象类本身中,您可以根据要对类层次结构进行的操作来执行几项操作。

  • 如果所有(或大多数)后代都需要处置逻辑,则可以使用以下方法强制他们实现处置模式的两种方法:

    public abstract void Dispose();
    public abstract void Dispose(bool disposing);
    

    这样,后代别无选择,只能执行这些方法,否则代码将无法编译。

  • 如果大多数类不需要处理,但其中一些仍需要处理,我将在基类中声明虚拟方法:

    public virtual void Dispose(){
      Dispose(true);
      GC.SuppressFinalize(this);
    }
    
    public virtual void Dispose(bool disposing){}
    

    对于大多数后代来说,这种默认实现已经足够了,那些需要处置的人可以随意覆盖它。

  • 而且,由于该Dispose()方法的代码几乎总是相同的,因此您可以实现该方法,而将另一个保留为虚拟甚至抽象。

    //should not be overridden
    public virtual void Dispose(){
      Dispose(true);
      GC.SuppressFinalize(this);
    }
    
    //must be overriden
    public abstract void Dispose(bool disposing);
    

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章