1. ホーム
  2. c#

[解決済み] コンストラクタ内の仮想メンバー呼び出し

2022-03-19 07:08:45

質問

オブジェクトのコンストラクタから仮想メンバを呼び出すと、ReSharperから警告が表示されるのですが。

なぜ、このようなことをしてはいけないのでしょうか?

どのように解決するのか?

C#で書かれたオブジェクトを構築する場合、初期化子は派生クラスから基底クラスの順に実行され、コンストラクタは基底クラスから派生クラスの順に実行されます ( この理由については、Eric Lippertのブログを参照してください。 ).

また、.NETでは、オブジェクトは構築される際に型が変わるのではなく、最初に最も派生した型として始まり、メソッドテーブルも最も派生した型に対応したものとなっています。つまり、仮想メソッドの呼び出しは常に最上位の派生型上で実行されます。

この2つの事実を組み合わせると、コンストラクタで仮想メソッドを呼び出したときに、そのクラスが継承階層の最上位にない場合、コンストラクタが実行されていないクラスで呼び出されることになり、そのメソッドを呼び出すのに適した状態でない可能性があるという問題が残ります。

もちろんこの問題は、クラスをsealedにして継承階層の最上位の派生型であることを確認すれば軽減されますし、その場合は仮想メソッドを呼び出してもまったく問題ありません。