C# 新关键字在派生类中的工作方式
我对new关键字有些困惑,当我使用virtual和override时,一切正常,但是new有点不同(我想我遗漏了一些东西) } 现在有了新的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"); }
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();
}
}