0

次のようなコードがたくさんあります。

public class MyWcfService : IMySerciceContract, IDisposable
{
    private DatabaseOperations _dataAccess;

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

    protected virtual void Dispose(bool disposing)
    {
        _dataAccess.Dispose();
    }
}

クラス MyWcfService が IIS または WAS でホストされ、明示的に Dispose を呼び出すことはありません。私の考えでは、このクラスに IDisposable を実装させるのは無意味であり、_dataAccess の使用を using ステートメントでラップする方がよいでしょう。私が理解しているように、IDisposable を実装するクラスの期待は、そのクラスのユーザーが using ブロック宣言でインスタンス化することです。Dispose を明示的に呼び出すユーザーがいないことを考えると、上記の例は悪い習慣ですか? 上記の例のようにクリーンアップを GC に依存している場合、GC は Dispose を呼び出しますか、それとも単にファイナライザーを呼び出しますか?

4

2 に答える 2

1

... 、誰も明示的に Dispose を呼び出すことはありません。私の考えでは、このクラスに IDisposable を実装させるのは無意味だと思います...

ポイントは、コードで呼び出すファイナライザーが不足していることDisposeです..

...私が理解しているように、IDisposableを実装するクラスの期待は、そのクラスのユーザーがusingブロック宣言でインスタンス化することです...

通常、実装するクラスの期待は、破棄するものIDisposableあることです。usingは単なる構文糖衣であり、実装する理由にはまったくなりませんIDisposable

... 上記の例のようにクリーンアップを GC に依存している場合、GC は Dispose を呼び出しますか?それとも単にファイナライザーを呼び出しますか?

GC はDispose自動的に呼び出されないため、ファイナライザーに呼び出させる必要があります。

public partial class MyWcfService: IMySerciceContract, IDisposable {
    private DatabaseOperations _dataAccess;

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

    protected virtual void Dispose(bool disposing) {
        if(!this.disposed) {
            if(disposing) {
                _dataAccess.Dispose();
            }

            this.disposed=true;
        }
    }

    // so it make sense now .. 
    ~MyWcfService() {
        this.Dispose(false);
    }

    bool disposed;
}

Disposeがコンシューマーによって呼び出されない場合、必要に応じてファイナライザーが呼び出します。[ IDisposable インターフェイス] の実装方法を参照してください。

于 2013-10-24T02:19:52.053 に答える
1

「DatabaseOperations _dataAccess」はクラス メンバーであり、クラスによって「所有」されています。それはIDisposableなので、あなたのクラスもそうあるべきです。また、一貫性を保つために、常に完全な標準の破棄パターンを実装する必要があります。

_dataAccess が、メソッド スコープ内で使用および破棄したクラス メソッド内のローカル変数である場合は、using ブロックが適切です。

原則として、コードのユーザーがクリーンアップを最大限に制御できるようにコーディングする必要があります。これは、メンバーのいずれかが IDisposable であることを意味します。しかし、メンバーではない IDisposable オブジェクトの場合は、「使用する」方法が適しています。

もちろん、同じことがクラスの消費者にも当てはまります。クラスをメンバー フィールドとして埋め込む場合は、クラスを IDisposable にする必要があります。それ以外の場合は、クラスオブジェクトで「using」を使用できます..など。

于 2013-10-24T02:22:02.983 に答える