(5/15追記:@shiracamusさんより指摘コメントあり、内容に間違いがあったため図解を差し替えています。)
overrideとnewの違いで少し混乱したためまとめ。
解説サイトはいくつもあるけれども、図解しているものがなかったため、図で考えてみた。
下記のような、BクラスがAクラスを継承している場合を考えてみる。
class A
{
public void Test_New() => Console.WriteLine("A::Test_New");
public virtual void Test_Override() => Console.WriteLine("A::Test_Override");
}
class B : A
{
public new void Test_New() => Console.WriteLine("B::Test_New");
public override void Test_Override() => Console.WriteLine("B::Test_Override");
}
実行を以下の様に行なうと、
A a = new B();
a.Test_New();
a.Test_Override();
B b = new B();
b.Test_New();
b.Test_Override();
つまり、図解(下記、@shiracamusさんのソースコードに基づいている)すると
となる。
overrideの場合、派生元のメソッドを文字通り上書きしに行くので、イメージとしてはAとBが重なり合う感じ。
newの場合も、文字通り追加するので、イメージとしてはインスタンス内に二つのメソッドが存在する。
この場合、呼ばれるのは型による。
(A.Test_New()やB.Test_New()とすると、型によって呼ばれる先が異なるのはイメージできると思う)
また、@shiracamusさんのソースコードについて考えてみると
class A
{
public int value = 123;
public void Test_New() {Console.WriteLine($"A::New : {value}");}
public virtual void Test_Override() {Console.WriteLine($"A::Override : {value}");}
}
class B : A
{
public new int value = 456;
public new void Test_New() {Console.WriteLine($"B::New : {value}");}
public override void Test_Override() {Console.WriteLine($"B::Override : {value}");}
}
について、図解の灰色の部分は呼ばれることはないので、
Console.WriteLine("A a = new B()");
A a = new B();
a.Test_New();
a.Test_Override();
((B)a).Test_New(); // b.Test_New()と同等
Console.WriteLine();
Console.WriteLine("B b = new B()");
B b = new B();
b.Test_New();
b.Test_Override();
((A)b).Test_New(); // a.Test_New()と同等
の結果は、@shiracamusさんの示された下記の通りになる。
A a = new B()
A::New : 123
B::Override : 456
B::New : 456
B b = new B()
B::New : 456
B::Override : 456
A::New : 123