这个代码块的输出对我来说没有意义
本文关键字:对我来说 有意义 输出 代码 | 更新日期: 2023-09-27 18:08:12
所有调用实例的运行时类型都是D,因此,F()的所有调用都应该是D中声明的F()方法。
using System;
class A
{
public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
static void Main() {
D d = new D();
A a = d;
B b = d;
C c = d;
a.F();
b.F();
c.F();
d.F();
}
}
输出为:
B.F
B.F
D.F
D.F
输出不应该是:
D.F
D.F
D.F
D.F
使用覆盖和新关键字进行版本控制(c#编程指南)
如果派生类中的方法前面有new关键字,该方法被定义为独立于基中的方法类。
所以A
和B
的F
方法与C
和D
的方法没有连接,这就是为什么你得到了你得到的。
在运行时CLR查找virtual
方法实现,应该从变量声明的类型开始使用,直到它真正的类型。对于a.F()
和b.F()
,它在B.F()
声明时停止,因为C.F()
是不同的方法(因为new
)。
不应该…
A a = d;
这意味着您正在创建一个类型为A
的类。并且由于您显式重写了类B
中的相关方法;A
使用B
类中的方法。
另一方面,在这一行;
new public virtual void F() { Console.WriteLine("C.F"); }
通过使用new
关键字,您声明您将不使用F()
方法。
如果在D
和C
类中重写了F()
方法,那么所有实例都将调用D
类中声明的F()
方法。
您在C:B类中使用new public virtual void F()
。说明C
类中的F()
和B
类中的F()
是不同的方法。
因此,当您将C
重写为D
类时,D
类中的F()
方法将从C
类重写,而不是从B
类重写。
另一个明显的例子是这样的:
C c = new C();
B b = c;
b.F();
c.F();