C# 新关键字在派生类中的工作方式

C# 新关键字在派生类中的工作方式,c#,new-operator,shadowing,C#,New Operator,Shadowing,我对new关键字有些困惑,当我使用virtual和override时,一切正常,但是new有点不同(我想我遗漏了一些东西) } 现在有了新的 class A { public void Test() { Console.WriteLine("I am in A"); } } class B:A { public new void Test() { Console.WriteLine("I am in B"); }

我对new关键字有些困惑,当我使用virtual和override时,一切正常,但是new有点不同(我想我遗漏了一些东西)

}

现在有了新的

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。
所以我错在哪里,这似乎是一个愚蠢的错误:-)

检查
新的
关键字用法。由于a被强制转换为,因此您正在调用a的方法,该方法无法重写。B恰好有一个同名的方法。

当您使用
new
关键字隐藏基类方法时,调用由编译器解析,而不是在运行时解析

因此,当您编写
a.Test
时,编译器会调用
a
类上的
Test
方法。即使
a
变量碰巧引用了
B
实例,编译器也不在乎,它仍然调用
a
上的版本


调用虚方法时,编译器会发出
callvirt
指令,告诉运行时根据实例的实际类型找到要调用的正确方法。运行时知道该实例实际上是
B
类型,并且会看到
B
重写该方法并调用重写的版本。

基本上,一旦创建了从
A
B
派生的其他类,您就会发现调用
base.Test()
将调用
A
的版本,用于那些
覆盖
而不是
新建
的类,而那些从
B
派生的类将调用
B
的版本,但不调用
A

“new”表示该方法是“new”而不是“override”。因此,如果您从基调用该名称的方法,则该方法尚未被重写,因此不会调用派生的方法


这意味着这是编译时vs运行时..我明白你的意思了,thnx。
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();
    }
}