5
interface IMyInterace
{
void Open();
object Read();
void Close();
}

class MyImplementation : IMyInterface
{
public void Open() { /* instantiates disposible class */ }
//...
public void Close() { /* calls .Dispose(); */ }

}

有没有一种很好的方法来处理这种情况,以确保类中的可处置实例被调用?(除了在文档中,没有信号通知调用者他们必须调用“关闭”。)IMyInterface 的实现不一定封装 IDisposible 实例,并且在应用程序的整个生命周期中反复关闭和​​重新打开。

我正在考虑这样做:

  • 在 MyImplementation 中实现 IDisposible。
  • 设置 Dispose() 以调用 Close()。
  • 在 Open 的开头添加对 Close() 或 Dispose() 的调用,以确保先前的调用已关闭。

IMyInterface 的用户不知道他们使用的是什么实现,所以我不确定使 MyImplementation disposible 有多少价值,而且,并非所有实现都会封装 IDisposibles。

4

3 回答 3

5

处理这个问题的标准方法是简单地MyImplementation 实现IDisposable

于 2010-12-30T19:38:15.650 回答
3

正如约翰所说,你的第一个要点是正确的。

有时,Close()方法在功能上与 同义Dispose(),并且存在以保持与抽象的语义一致性。也就是补充一个Open()方法。其他时候,Close()会允许你重新打开,但Dispose()不应该。因此,您的第二个要点也很好。

要点 3 不一定适用,因为不应重复使用已处置的对象。如果需要Open()再次调用,则需要使用新实例。事实上,该Open()方法应该抛出一个ObjectDisposedException曾经Dispose()被调用过的方法(通过检查私有disposed布尔标志)。如果您希望对象在关闭后支持重新打开,您可以考虑使用Debug.Assert()和/或在Open()没有Close(). 这将有助于防止对这些实例的草率管理。

一定要遵循完全一次性的模式,这比简单地实现接口更复杂:

bool disposed;

public void Dispose() // don't make virtual!
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if(!disposed)
    {
        if(disposing) 
        {
            // dispose of managed resources here, for example:
            // if(resource != null) { resource.Dispose(); } 
        }
    }

    // dispose of unmanaged resources here 

    disposed = true;
}
于 2010-12-30T19:51:28.273 回答
1

除了这里已经有的答案:

如果这个类(经常/有时)仅通过接口使用,我建议从 IDisposable 继承 IMyInterace。

这将使您的用户以一致的方式使用这些对象。缺点当然是您可能需要向实际上不需要它的类添加(虚拟)Dispose 方法。但好处在于一致性和灵活性:如果一个类在未来发生变化以至于它确实需要 Dispose() 怎么办?

最小的方法:

interface IMyInterace : IDisposable { }

sealed class MyImplementation : IMyInterface 
{   
   public void Open() { /* instantiates disposible class */ }

   public void Close() { /* calls _myField.Dispose(); */ }

   public void Dispose() { Close(); }  // only use this short form in a sealed class

}
于 2010-12-30T20:04:25.620 回答