I was wondering why some casts in C# are checked at compile-time whereas in other cases the responsibility is dumped on 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:
"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."
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
. This is unrelated to Derived
so the cast fails at compile time.
Base x = new Base();
Derived d = (Derived)x;
The static type of x
is now Base
. Something of type Base
might have dynamic type Derived
, so this is a downcast. 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
. So the decision of whether the cast is allowed is left to the runtime.