繁体   English   中英

编译时和运行时强制转换C#

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM