[英]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? “理论上”是指通过继承层次结构(对象之间的另一种亲缘关系?)相连还是编译器的内部事务?
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.