new 关键字在派生类中如何工作
我对 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();
}
}
}
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。 所以我出错的地方似乎是一个愚蠢的错误:-)
I am having some confusion with the new keyword,things work fine when I am using virtual and override , but a bit different with new(I think I am missing something)
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();
}
}
}
Now with 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();
}
}
as per MSDN When the new keyword is used, the new class members are called instead of the base class members that have been replaced. Those base class members are called hidden members, also the GetType() is Showing type as B.
So where I am going wrong, seems its a silly mistake :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您使用 new 关键字隐藏基类方法时,该调用将由编译器解析,而不是在运行时解析。
因此,当您编写
a.Test
时,编译器会发出对A
类上的Test
方法的调用。即使a
变量碰巧引用B
实例,编译器也不会关心,它仍然调用A
上的版本。当您调用虚拟方法时,编译器会发出
callvirt
指令,告诉运行时根据实例的实际类型查找要调用的正确方法。运行时知道该实例实际上是B
类型,并且会看到B
覆盖该方法并调用覆盖的版本。When you hide a base-class method using the
new
keyword, the call is resolved by the compiler, not at runtime.Therefore, when you write
a.Test
, the compiler emits a call to theTest
method on theA
class. Even though thea
variable happens to refer to aB
instance, the compiler doesn't care, and it still calls the version onA
.When you call a virtual method, the compiler emits a
callvirt
instruction that tells the runtime to find the correct method to call based on the actual type of the instance. The runtime is aware that the instance is actually of typeB
, and will see thatB
overrides the method and call the overridden version.查看 Jon Skeet 的描述n
new< /code> 关键字用法。因为 a 被强制转换为 A,所以您正在调用 A 的方法,该方法不能被重写。 B 恰好有一个同名的方法。
Check out Jon Skeet's description of the
new
keyword usage. Because a is cast as A, you are calling A's method, which cannot be overridden. B just happens to have a method with the same name.基本上,一旦您创建了从
A
或B
派生的其他类,您就会发现调用base.Test()
将调用 <对于那些重写
而不是new
的类以及从B
派生的类,code>A的版本将具有B
的版本被调用,但不是A
的版本。Basically, once you create additional classes which derive from either
A
orB
, you'll find that callingbase.Test()
will callA
's version for those classes whichoverride
rather thannew
and those which derive fromB
will haveB
's version called but NOTA
's.