18

Start()ここでの問題は、オブジェクトを派生クラスに渡したいということですが、基本クラスはオブジェクトを使用する派生クラスのメソッドをすぐに呼び出すため、基本クラスのコンストラクターの前に行う必要があります。

以下は、基本クラスからの抜粋です (便宜上、 BarcodeScannerから名前が変更されています)。

public abstract class MyBase
{    
    public MyBase()
    {
        if (Initialize())
            this.Start();
    }

    public abstract bool Initialize();
    public abstract void Start();
}

これが私が作成している派生クラスです。

class MyDerived : MyBase
{
    private string sampleObject;

    public MyDerived (string initObject)
    {
        sampleObject = initObject;
    }

    public override bool Initialize() 
    { 
        return GetDevice();
    }
    public override void Start() 
    { 
        Console.WriteLine("Processing " + sampleObject.ToString()); 
    }
}

基本コンストラクターの前に派生コンストラクターを C# で実行できるとは思えません。オブジェクトが使用される前に、オブジェクトを派生クラスに渡すためのソリューションを本当に探しています。

MyDerivedコンストラクター内に Initialize/Start if ブロックを配置することで、これを回避しました。ただし、基本クラスから派生する他のクラスがあります。そのため、すべての派生クラスでこの初期化/開始コードのブロックを繰り返さなければならなくなりました。基本クラスを変更する代わりの方法を知りたいです。

4

4 に答える 4

22

あなたがやろうとしていることは、C# では不可能です。基本クラスのコンストラクターは、派生クラスのコンストラクターの前に実行する必要があります。そうしないと、オブジェクトの状態が破損する可能性があります。子オブジェクトは、そのベースが完全に構築され、利用可能であると想定できなければなりません。

于 2009-04-09T17:24:16.167 に答える
21

私見あなたのデザインは間違っています。コンストラクター内からプロセスを開始しないでください。消費するコードは、必要に応じて Start() メソッドを明示的に呼び出す必要があります。

于 2009-04-09T17:25:41.047 に答える
1

Initialize (および場合によっては Start() - 通常、これはユーザーによって呼び出されるパブリック メソッドですが) が構築後に呼び出されるように、設計を作り直します。

BarcodeScanner を作成している場合は、最初にスキャンするときにこれを行うことができます。派生クラスのデータを使用してメンバーを遅延初期化するだけです。

これにより、ユーザーの使用状況が実際に変わることなく、問題を回避できます。

于 2009-04-09T17:29:45.267 に答える