2017-08-14 7 views
0

は、以下のクラスを仮定しますctorに作成されていないフィールドのパターンを削除しますか?

public class MyClass : IDisposable 
{ 
    protected MyDisposableType1 _object1; 
    protected MyDisposableType2 _object2; 

    public MyClass() 
    { 
    } 

    public StartActivity1() 
    { 
     _object1 = new MyDisposableType1(); 
    } 

    public StopActivity1() 
    { 
     _object1.Dispose(); 
     _object1 = null; 
    } 

    public StartActivity2() 
    { 
     _object2 = new MyDisposableType2(); 
    } 

    public StopActivity2() 
    { 
     _object2.Dispose(); 
     _object2 = null; 
    } 

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

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      ... 
     } 
    } 
} 

Dispose patternによると、私のクラスは、使い捨てタイプのフィールドを所有しているので、私はIDisposeableを実装する必要があります。しかし、すべてのDisposeパターンの例では、ctorで作成された使い捨てフィールドを扱っています。この場合、処分パターンは明らかです。しかし、ユーザーがMyClassライフサイクルの間に自分の使い捨てフィールドを複数回作成して破壊することができたらどうなりますか? Disposeパターンも使用する必要がありますか、またはいくつかのユースケースがありますか?

+0

あなたがダウンボートを持っている理由はわかりませんが、私にとっては妥当な質問のようです。私はこの設計上の問題が、あなたのロジックを1つのクラスに正しくパッケージ化していないために浮上したのだろうかと思います。メソッドStartActivity1()とStartActivity2()はクラスインスタンスの状態を共有しますか? – camelCase

+0

@camelCase申し訳ありませんが、あなたは "メソッドStartActivity1()とStartActivity2()はクラスインスタンスの状態を共有しますか?" – gustav

+0

私は、アクティビティ1とアクティビティ2のロジックを、基本クラスの共有ロジック(ただしインスタンス状態ではない)を持つ別のクラスにデカップリングできますか?私はあなたのパターン設計のジレンマが最初にどのようにして起きたのか疑問に思っています。とにかくあなたの主な質問に良い答えがあります。 – camelCase

答えて

2

通常、Disposeメソッドでもフィールドを廃棄してみます。

protected virtual void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     _object1?.Dispose(); 
     _object2?.Dispose(); 
    } 
} 

ザ・ようなものがあるでしょう "?" - オブジェクトがnullの場合オペレータは、使用されます。 stopメソッド(つまり "StopActivity2")が既に呼び出されている場合、これで例外はありません。

+0

もちろんこれは可能です。しかし、ユーザーは 'Dispose()'を呼び出した後でMyClassを使用することができないと予想しています。しかし、彼はStartActivity()をもう一度呼び出すことができるので、実際に行うことができます。 – gustav

+0

通常、使い捨てのクラスは、usingキーワードと共に使用されます。それで、すべてうまく動作します。 – Oswald

+0

実際にコードの他の部分から 'StartActivity()'と 'StopActivity()'を呼び出すため、 'using 'で' MyClass'を使用することはできません。だから、これは私の質問です。たぶんDisposeパターンは私の特定のタスクのために修正されるべきですか? – gustav

1

MyClassを配置した後に、配置されたオブジェクトに依存するメソッドをユーザーが呼び出せないようにしてください。ブール値を使用することでこれを防ぐことができます。

bool _disposed; 

public StartActivity1() 
{ 
    if(_disposed) return; // or throw exception. 
    _object1 = new MyDisposableType1(); 
} 

public StopActivity1() 
{ 
    _object1?.Dispose(); 
    _object1 = null; 
} 

//... 

protected virtual void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     _object1?.Dispose(); 
     _object2?.Dispose();    
     _disposed = true 
    } 
} 
+0

再使用後の廃棄を防ぐことについての良いお話。この公式のアドバイスは、パターン文書またはあなたの個人的な洗練された状態で質問に提示されているか? – camelCase

+2

これは公式です。[Dispose pattern](https://docs.microsoft.com/ja-jp/pt-br/dotnet/standard/design-guidelines/dispose-pattern)の記事をご覧ください。 – gustav

+1

このパターンは、 'Dispose()'の状態が呼び出された後に使用されるため、このパターンが使用されています。 'MyClass'は使用するのが不可能になりますよね?しかし、私の場合、使い捨てオブジェクトはctorで作成されず、再度作成することができ、 'StartActivity()'を呼び出すことで 'MyClass'を引き続き使用することができます。 – gustav

関連する問題