2

IDisposable インスタンスの注入を可能にするかなり標準的な抽象クラスがある場合。ただし、このクラスから継承する一部のクラスは、他のクラスと同様に、注入されたリポジトリを破棄してはなりません。明らかな解決策は、コンストラクターを持つことです。

public abstract class WorkspaceViewModel : IDisposable
{
    readonly bool _cascadeDisposeRepository;
    protected WorkspaceViewModel(IRepository repository, bool cascadeDisposeRepository=true)
    {
        _repository = repository;
        _cascadeDisposeRepository = cascadeDisposeRepository;
    }

編集:

私もコンストラクタを持っていました

    protected WorkspaceViewModel()
        :this(new RepositoryA(), true){} 

編集を終了

次に、マイクロソフトが推奨する方法で Dispose メソッドを実装します。

protected virtual void Dispose(bool disposing)
{
    if (!_disposed)
    {
        if (disposing)
        {
            if (_cascadeDisposeRepository) { _repository.Dispose(); }
            .....

しかし、私は IDisposable がこのように実装されているのを見たことがなく、それが悪い習慣であるかどうか疑問に思っていました (もしそうなら、なぜ、そして他の解決策が望ましいでしょうか)。

ご感想ありがとうございます。

編集: マークのコメントにより、WorkspaceViewModel から継承するすべてのクラスに、WorkspaceViewModel の実装されたインターフェイスから IDisposable を削除しながら、独自のインスタンスを作成して破棄する (そして IDisposable を実装することを選択する) ことを強制する、パラメーターのないコンストラクターを使用しないことが望ましい実装である可能性があることに気付きました。

4

2 に答える 2

0

を実装するオブジェクトを「使用」する最後のエンティティはIDisposable、直接アクセスするか、既知の期間一時的に使用するために他のエンティティに渡すことによって、それを呼び出す必要がDisposeあります。MoeMoe がそれをいつ処理するかを本質的に知っている他のエンティティからが渡された場合IDisposable、Moe は通常、他のエンティティがそれを処理し、Dispose自分自身を呼び出す必要はないと期待できます。実際、IDisposableMoe がそれを使い終わった後、他のエンティティが を使用する可能性がある場合、Moe は自分自身を呼び出してはなりませDisposeMoeインターフェイスまたは基本クラス型の参照が渡された場合、インターフェイスまたは基本クラスを実装する必要はありませんIDisposable; 渡されたインスタンスが を実装する派生型であったとしてもIDisposable、それは Moe の関心事ではありません。そのインスタンスを作成したエンティティは、それがそれを実装IDisposableして処理するタイプであることを認識している必要があります。

注意が必要なのは、ファクトリ メソッドの場合です。ファクトリ メソッドが を実装するオブジェクトを返すという現実的な可能性がありIDisposable、そのメソッドの呼び出し元だけがオブジェクトがいつ不要になるかを知ることができる場合、そのメソッドの戻り値の型自体が を実装する必要がありますIDisposable。非ジェネリックIEnumeratorインターフェイスはそのパターンに従わなかったため、非ジェネリック インターフェイスを使用するコードは、IEnumerable各オブジェクトが実装によって返されたかどうかを確認し、そうであればそれを呼び出す必要がGetEnumerator()ありますIDisposable。これは、[実装の 99.9% だけが do-nothing を持っている場合でも、継承されていた場合に無条件Disposeに呼び出すよりも便利ではなく、遅くなります。IDisposableIEnumeratorIEnumeratorDisposeインターフェイスがサポートすることがわかっている何もしないメソッドを呼び出す方が、インターフェイスがメソッドをサポートしているかどうかを確認するよりも高速です]。 ファクトリ メソッドの戻り値の型を実装または継承IDisposableしても、呼び出し元に責任が追加されるわけではないことに注意してください。

于 2013-10-21T16:50:44.537 に答える