コンストラクタ内の仮想メンバー呼び出し 質問する

コンストラクタ内の仮想メンバー呼び出し 質問する

オブジェクト コンストラクターからの仮想メンバーの呼び出しについて、ReSharper から警告が表示されます。

なぜこれをしてはいけないのでしょうか?

ベストアンサー1

C#で書かれたオブジェクトが構築されるとき、初期化子は最も派生したクラスから基底クラスまで順に実行され、次にコンストラクタは基底クラスから最も派生したクラスまで順に実行されます(なぜそうなるのかについては、エリック・リッパートのブログをご覧ください。)。

また、.NET では、オブジェクトは構築時に型を変更せず、最も派生した型として開始され、メソッド テーブルは最も派生した型用になります。つまり、仮想メソッド呼び出しは常に最も派生した型で実行されます。

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

もちろん、クラスをシールとしてマークして、継承階層内で最も派生した型になるようにすれば、この問題は軽減されます。その場合、仮想メソッドを呼び出すのは完全に安全です。

おすすめ記事