0

基本クラスに属するオブジェクトの作成に影響を与える、基本クラスで定義されたフィールドが必要です。ただし、 Baseクラスcto'rが呼び出される前に、フィールドの値をオーバーライドできるようにしたいです。例:

class ObjNeedParam
{
    public ObjNeedParam(int p)
    {
        val = p;
    }
    int val;
    int Value{get{return Value;}}
}
class Base
{
    public Base()
    {
        obj = new ObjNeedParam(paramVal);
    }
    ObjNeedParam obj;
    protected int paramVal = 1;
}

class Derived : Base
{
    public Derived()
    { 
        //Once I'm here, obj has already been created with paramVal=1 instead of 2!            
        dummy = 3;
    }
    new int paramVal = 2;
    int dummy;
}
4

2 に答える 2

3

この方法はやや疑わしいので、ここでアプローチを再考することをお勧めします。

それでもこれを続行したい場合、正しい方法は、virtualこの値を基本コンストラクターに提供するメソッドを用意することです。

class Base
{
    public Base()
    {
        obj = new ObjNeedParam(GetParamVal());
    }

    protected virtual int GetParamVal() { return 1; }
}

class Derived : Base
{
    protected override int GetParamVal() { return 2; }
}

のコンストラクターで初期化されるoverrideクラスメンバーを使用しないようにするDerivedDerived必要があります。これは、そのコンストラクターがオーバーライドが呼び出された時点ではまだ実行されていないためです。コンストラクターでの仮想メンバー呼び出しを参照してください。

更新:派生型のオブジェクトを作成する場合、コンパイラーには解決すべき問題があるため、多少疑問があります。フィールドを初期化し、コンストラクターを実行して、コンストラクター内からのメソッド呼び出しでオブジェクトが確実に見つかるようにする必要があります。 「使用可能な」状態ですか?

定義上、すべてのコンストラクターが返されるまでオブジェクトは使用可能な状態ではなく、これらのコンストラクターからメソッドを呼び出すことについて話しているため、この問題は一般的なケースでは解決できません。したがって、コンパイラは可能な限り保証し、安全ではないことを防止または許可する必要があります。

このシナリオでは、C ++は(面白いことに)安全ではないことを防止しますが、C#はそれを許可します。したがって、注意を怠るとバグが発生する可能性があるため、多少疑問があります。より安全なアプローチは、コンストラクターの実行後にこのメンバーが初期化されるようにクラスを作成することです。

于 2012-07-18T09:35:38.743 に答える
1

あなたがする必要があるのは、そのようにフィールドを初期化することではありません。1つの代替方法は、フィールドをプロパティにし、子クラスによるオーバーライドを許可することです。または、パラメーターを介して基本クラスコンストラクターでフィールドを設定できるようにして、次のようなコードを記述できるようにします。

class Base
{
    public Base() : this(1)
    {
    }

    public Base(int param)
    {
        paramVal = param;
    }

    private int paramVal;
}

class Derived : Base
{
    public Derived() : base(2)
    {   
    }
}

最終的に、フィールドは通常、クラスに対してプライベートであり、派生クラスによってオーバーライドされることはありません。派生クラスが操作できるように公開する場合は、フィールド以外のものが必要になる可能性があります。

于 2012-07-18T09:40:21.700 に答える