在C#中,运行时类型和编译时类型之间的区别是什么,这对虚方法调用有什么影响?
假设我们有两个类A
和B
声明如下:
internal class A
{
internal virtual void Test() => Console.WriteLine("A.Test()");
}
internal class B : A
{
internal override void Test() => Console.WriteLine("B.Test()");
}
B
继承自A
并覆盖了打印消息到控制台的Test
方法。
C#中运行时类型和编译时类型有什么区别?
现在考虑以下语句:
A test = new B();
在编译时:编译器只知道变量test
是A
类型,他不知道我们实际上给他一个B
的实例。因此,test
的编译时类型是A
。
在运行时:test
的类型已知为B
,因此具有B
的运行时类型。
关于虚方法调用,有哪些影响?
考虑以下代码语句:
((A)new B()).Test();
我们创建了一个B
的实例,并将其强制转换为A
类型,并在该对象上调用Test()
方法。编译时类型是A
,运行时类型是B
。
当编译器想要解析.Test()
调用时,他遇到一个问题。因为A.Test()
是virtual
的,编译器不能简单地调用A.Test
,因为存储的实例可能已经覆盖了该方法。
编译器本身无法确定调用哪个方法A.Test()
还是B.Test()
。调用的方法由运行时决定,而不是由编译器“硬编码”。