4

new キーワードと混乱しています。 virtual と override を使用しているときは問題なく動作しますが、 new とは少し異なります (何かが足りないと思います)。

 class A
{
    public virtual void Test()
    {
        Console.WriteLine("I am in A");
    }
}

class B:A
{
    public override void Test()
    {
        Console.WriteLine("I am in B");
    }
}


class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Test(); //I am in B
        A a = new B();
        Console.WriteLine(a.GetType()); // Type-B
        a.Test(); //I am in B
       Console.ReadKey();
    }
}

}

今、新しい

class A
{
    public  void Test()
    {
        Console.WriteLine("I am in A");
    }
}

class B:A
{
    public new void Test()
    {
        Console.WriteLine("I am in B");
    }
}


class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Test(); //I am in B
        A a = new B();
        Console.WriteLine(a.GetType()); //B
        a.Test(); // I am in A ? why?
       Console.ReadKey();
    }
}

MSDN によると、 new キーワードが使用されると、置き換えられた基本クラス メンバーの代わりに、新しいクラス メンバーが呼び出されます。これらの基本クラスのメンバーは非表示のメンバーと呼ばれ、GetType() は型を B として表示しています。

4

4 に答える 4

2

キーワードの使用法に関する Jon Skeet の説明を参照してください。newa は A としてキャストされるため、オーバーライドできない A のメソッドを呼び出しています。B はたまたま同じ名前のメソッドを持っているだけです。

于 2010-02-22T18:21:51.303 に答える
2

newキーワードを使用して基本クラスのメソッドを非表示にすると、呼び出しは実行時ではなく、コンパイラによって解決されます。

したがって、 を記述するa.Testと、コンパイラはクラスのTestメソッドへの呼び出しを発行します。変数がたまたまインスタンスを参照してAいても、コンパイラは気にせず、バージョン on を呼び出します。aBA

仮想メソッドを呼び出すと、コンパイラはcallvirt、インスタンスの実際の型に基づいて呼び出す正しいメソッドを見つけるようにランタイムに指示する命令を発行します。ランタイムは、インスタンスが実際には type であることを認識しており、それがメソッドをオーバーライドし、オーバーライドされたバージョンを呼び出すBことを確認します。B

于 2010-02-22T18:23:23.003 に答える
0

A基本的に、 または のいずれかから派生する追加のクラスを作成すると、 のバージョンではなくのバージョンが呼び出され、から派生するクラスでは のバージョンが呼び出されるが、 のバージョンは呼び出されないBことがわかります。base.Test()AoverridenewBBA

于 2010-02-22T18:23:58.507 に答える
0

The "new" means the method is "new" and not an "override". Therefore, if you call a method by that name from the base, it hasn't been overriden so the derived won't be called.

于 2018-10-26T14:55:00.103 に答える