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() を呼び出します。
  • Close() または Dispose() への呼び出しを Open の先頭に追加して、前の呼び出しが確実に閉じられるようにします。

IMyInterface のユーザーは自分が使用している実装を知らないため、MyImplementation をディスポーザブルにする価値がどれほどあるのかわかりません。また、すべての実装が IDisposibles をカプセル化するわけではありません。

4

3 に答える 3

5

これを処理する標準的な方法は、単にMyImplementation 実装することIDisposableです。

于 2010-12-30T19:38:15.650 に答える
3

As John mentioned, your first bullet point is right on.

Sometimes a Close() method is functionally synonymous with Dispose(), and exists to maintain semantic consistency with an abstraction. That is, to complement a Open() method. Other times, Close() will allow you to re-open, but Dispose() should not. Your second bullet-point is therefore fine, as well.

Bullet point 3 is not necessarily applicable, because a disposed object should not be reused. If you need to call Open() again, you need to use a new instance. In fact, the Open() method should throw an ObjectDisposedException once Dispose() have been called (by checking a private disposed boolean flag). If you want the object to support re-opening after close, you might consider using Debug.Assert() and/or throwing an exception if Open() is called without Close(). This will help to prevent sloppy management of these instances.

Be sure to follow the full disposable pattern, which is more involved than simply implementing the interface:

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 に答える