6

今日、私は興味深い問題を思いつきました。次のコードに気付きました:

class A
{
    public A()
    {
        Print();
    }
    public virtual void Print()
    {
        Console.WriteLine("Print in A");
    }
}

class B : A
{
    public B()
    {
        Print();
    }

    public override void Print()
    {
        Console.WriteLine("Print in B");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new B();
    }
}

版画

Print in B
Print in B

「Print in B」が 2 回印刷される理由を知りたいです。

4

5 に答える 5

11

「Print in B」が 2 回印刷される理由を知りたいです。

同じオブジェクトで仮想メソッドを 2 回呼び出しています。オブジェクトはBeven duringAのコンストラクタのインスタンスであるため、オーバーライドされたメソッドが呼び出されます。(C++では、ポリモーフィズムに関する限り、オブジェクトは基本クラスのコンストラクターが実行された後にのみサブクラスのインスタンスに「なる」と思います。)

これは、コンストラクターから呼び出されたオーバーライドされたメソッドが、派生クラスのコンストラクター本体が実行される前に実行されることに注意してください。これは危険です。まさにこの理由から、コンストラクターから抽象メソッドまたは仮想メソッドを呼び出すことはほとんどありません。

: this(...)編集:「チェーン」への別のコンストラクター呼び出しを使用してまたはコンストラクター宣言で提供しない場合: base(...)、それは using と同等であることに注意してください: base()。したがって、Bのコンストラクターは次と同等です。

public B() : base()
{
    Print();
}

コンストラクター チェーンの詳細については、トピックに関する私の記事を参照してください。

于 2012-09-28T17:12:23.590 に答える
2

基本クラスのコンストラクターを呼び出さない場合、基本クラスの既定のコンストラクターが暗黙的に呼び出されます ( MSDN )。

クラス A コンストラクターを次のように定義した場合、二重の出力は得られません。

class A
{
    public A()
    {
        // does nothing
    }

    public A(object a)
    {
        Print();
    }
}

「Print in B」を両方とも出力する理由は、Print() がクラス B でオーバーライドされるため、B.Print() が両方のコンストラクターによって呼び出されるためです。

次のように、 A コンストラクターで A.Print() を強制的に呼び出すことができると思います。

class A
{
    public A()
    {
        ((A)this).Print();
    }
}

お役に立てれば。

于 2012-09-28T17:19:59.273 に答える
2

コンストラクターでの仮想の呼び出しがクラス自体内の定義に制限されている C++ とは異なり、オーバーライドは C# のコンストラクターで完全に受け入れられます。この慣行は嫌われており、正当な理由 (リンク) がありますが、それでも許可されています。Aのコンストラクターは、 が提供するオーバーライドを呼び出し、表示されるB出力を生成します。これは、オーバーライドされた仮想関数の通常の動作です。

于 2012-09-28T17:12:16.597 に答える
2

BオーバーライドはPrintメソッドだからです。変数aのタイプBは で、B のPrintメソッドは次のようになります。

public override void Print()
{
    Console.WriteLine("Print in B");
}
于 2012-09-28T17:12:25.943 に答える
1

Print をオーバーライドする B のインスタンスがあるため、オーバーライドされたメソッドが呼び出されます。また、A の ctor が実行され、続いて B が実行されるため、2 回印刷されます。

于 2012-09-28T17:12:29.390 に答える