简体   繁体   English

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

[英]Compile-time and runtime casting c#

I was wondering why some casts in C# are checked at compile-time whereas in other cases the responsibility is dumped on CLR. 我想知道为什么在编译时检查C#中的某些强制类型转换,而在其他情况下将责任转交给CLR。 Like above both are incorrect but handled in a different way. 像上面一样,两者都是错误的,但是以不同的方式处理。

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...
}

While reading "C# in depth" I've found the information on this topic where autor says: 在阅读“ C#深入”时,我发现了有关该主题的信息,指导者说:
"If the compiler spots that it's actually impossible for that cast to work, it'll trigger a compilation error—and if it's theoretically allowed but actually incorrect at execution time, the CLR will throw an exception." “如果编译器发现该强制转换实际上是不可能的,它将触发编译错误-如果理论上允许但实际上在执行时不正确,则CLR将引发异常。”

Does 'theoretically' mean connected by inheritance hierarchy (some another affinity between objects ?) or it is compiler's internal business? “理论上”是指通过继承层次结构(对象之间的另一种亲缘关系?)相连还是编译器的内部事务?

  • Upcasts can be checked at compile time - the type system guarantees that the cast succeeds. 可以在编译时检查向上转换-类型系统保证强制转换成功。
  • Downcasts cannot (in general) be checked at compile time, so they are always checked at runtime. 向下转换(通常)不能在编译时进行检查,因此始终在运行时进行检查。
  • Unrelated types cannot be cast to each other. 无关类型不能相互转换。

The compiler considers only the static types. 编译器仅考虑静态类型。 The runtime checks the dynamic (runtime) type. 运行时检查动态(运行时)类型。 Looking at your examples: 查看您的示例:

Other x = new Other();
Derived d = (Derived)x; 

The static type of x is Other . x的静态类型为Other This is unrelated to Derived so the cast fails at compile time. 这与“ Derived无关,因此强制转换在编译时失败。

Base x = new Base();
Derived d = (Derived)x; 

The static type of x is now Base . x的静态类型现在为Base Something of type Base might have dynamic type Derived , so this is a downcast. Base类型的东西可能具有动态类型Derived ,所以这是一个垂头丧气的事情。 In general the compiler can't know from the static type of x if it the runtime type is Base , Derived , of some other subclass of Base . 通常,编译器无法从x的静态类型中得知运行时类型是否是Base的其他子类的Base Derived So the decision of whether the cast is allowed is left to the runtime. 因此,是否允许强制转换的决定留给运行时。

If your variable is of Base type, is can be theoretically constructed by Derived constructor, thus being a variable of Derived type actually. 如果您的变量是Base类型,则理论上可以由Derived构造函数构造,因此实际上是Derived类型的变量。 At compile time, compiler does not bother itself with trying to figure out whether in each particular case such downcast (representing a variable of Base type as an entity of Derived type) is possible. 在编译时,编译器不会试图弄清楚在每种特定情况下是否都可能进行这种下调(将Base类型的变量表示为Derived类型的实体),这使编译器不会费心。

Your sample is simple - you create a new class and cast it right away. 您的示例很简单-您创建一个新类并立即进行投射。 But what if you get Base from somewhere else, eg, some method call? 但是,如果您从其他地方获得Base ,例如某个方法调用,该怎么办? Compiler just cannot "guess" what your method is going to return and therefore throw on not throw an error. 编译器无法“猜测”您的方法将返回什么,因此抛出错误不会抛出错误。

When you cast Other , compiler sees that there is no possibility that Other is actually Derived and throws an exception. 当您转换Other ,编译器会发现Other实际上没有Derived并会引发异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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