0

私は次のクラス階層を持っています-

//Abstract Class1 in library1 (Can't modify this)
public abstract class absClass1 : IDisposable
{
    public abstract int AddTwoNumbers(int Num1, int Num2);
    // Some other overrides, abstract methods and concrete methods

    void Dispose()
    {
       // Standard Dispose impl.
    }
}

//Abstract Class2 in library2
public abstract class absClass2 : absClass1
{
    //Implementing AddTwoNumbers
    public override int AddTwoNumbers(int Num1, int Num2)
    {
       return Num1+Num2;
    }

    public abstract int MultiplyTwoNumbers(int Num1, int Num2);

    // Some other overrides, abstract methods and concrete methods

    protected override void Dispose(bool disposing)
    {
        if (!IsDisposed)
        {
            //Cleanup
        }

        base.Dispose(disposing);
    }
}

//Derived class from absClass2 in library3
public sealed class absDerived1 : absClass2
{
    //Implementing MultiplyTwoNumbers
    public override int MultiplyTwoNumbers(int Num1, int Num2)
    {
       return Num1*Num2;
    }

    // Some other overrides, abstract methods and concrete methods

    protected override void Dispose(bool disposing)
    {
        if (!IsDisposed)
        {
            // Cleanup
        }

        base.Dispose(disposing);
    }
}

//... Some more implementation of absClass2 like absDerived2 etc.
//  can be there in other library4...

absClass2との両方でオブジェクトを破棄したいのですabsDerivedが、これらの両方のクラスでDispose(bool)をオーバーライドすることに問題はありますか?このデザインに問題はありますか?これをどのように改善できますか?

4

2 に答える 2

1

これは正しいです。参照のタイプに関係なく、オブジェクトabsDerviedabsClass1クラスDispose()が仮想Dispose(bool)を呼び出すDispose()と、参照を呼び出すと、Disposeまでのすべてのクラスのメソッドが呼び出されabsClass1ます。

そのメソッド(on absClass1)は仮想メソッドDispose(bool)を呼び出します。仮想メソッドは最も派生したメソッド(on absDerived)を呼び出し、最もbase.Dispose(disposing)近い基本クラス(ie )のメソッドを呼び出します。このメソッドには、のメソッドを呼び出すabsClass2呼び出しも含まれています。base.Dispose(disposing)absClass1

そのクラス構造をコンソールアプリに配置し、いくつかのWriteLineステートメントをDisposeメソッドに配置すると、Dispose()が呼び出されたときにすべてが起動することがわかります。

于 2012-06-18T13:51:05.927 に答える
1

これは現在コンパイルされませんが、なぜコンパイルされないのか尋ねていないのでvoid Dispose()、簡潔にするために定義を省略したと思います。

これは、正しく呼び出してbase.Dispose、基本クラスではなく現在のクラスのローカルにあるものを破棄することだけを心配している限り、問題ありませbase.Disposeん。これは、これを行うことに依存しているためです。

呼び出すbase.<member>と、現在のタイプの直接ベースタイプが呼び出されるだけなので、この場合absDerivedはになりabsClass2、はになりabsClassます。

私の唯一の観察は、を呼び出す前に現在のタイプのものを破棄することに注意する必要があるということですbase.Dispose。ものがどのように関連しているかによっては、最初に基本のものを破棄し、次に現在のタイプを破棄することをお勧めしますが、これは実際に破棄するものと順序が重要かどうかに完全に依存します。

于 2012-06-18T13:51:15.253 に答える