[英]Compile-time and runtime casting c#
我想知道为什么在编译时检查C#中的某些强制类型转换,而在其他情况下将责任转交给CLR。 像上面一样,两者都是错误的,但是以不同的方式处理。
class Base { }
class Derived : Base { }
class Other { }
static void Main(string[] args)
{
Derived d = (Derived)new Base(); //Runtime InvalidCastException
Derived d = (Derived)new Other(); //Compile-time Cannot convert type...
}
在阅读“ C#深入”时,我发现了有关该主题的信息,指导者说:
“如果编译器发现该强制转换实际上是不可能的,它将触发编译错误-如果理论上允许但实际上在执行时不正确,则CLR将引发异常。”
“理论上”是指通过继承层次结构(对象之间的另一种亲缘关系?)相连还是编译器的内部事务?
编译器仅考虑静态类型。 运行时检查动态(运行时)类型。 查看您的示例:
Other x = new Other();
Derived d = (Derived)x;
x
的静态类型为Other
。 这与“ Derived
无关,因此强制转换在编译时失败。
Base x = new Base();
Derived d = (Derived)x;
x
的静态类型现在为Base
。 Base
类型的东西可能具有动态类型Derived
,所以这是一个垂头丧气的事情。 通常,编译器无法从x
的静态类型中得知运行时类型是否是Base
的其他子类的Base
Derived
。 因此,是否允许强制转换的决定留给运行时。
如果您的变量是Base
类型,则理论上可以由Derived
构造函数构造,因此实际上是Derived
类型的变量。 在编译时,编译器不会试图弄清楚在每种特定情况下是否都可能进行这种下调(将Base
类型的变量表示为Derived
类型的实体),这使编译器不会费心。
您的示例很简单-您创建一个新类并立即进行投射。 但是,如果您从其他地方获得Base
,例如某个方法调用,该怎么办? 编译器无法“猜测”您的方法将返回什么,因此抛出错误不会抛出错误。
当您转换Other
,编译器会发现Other
实际上没有Derived
并会引发异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.