Компилятор Проверка статического типа означает, что если A и B не принадлежат к одной и той же иерархии наследования, это не позволит выполнить приведение между ними.
Подумайте об этом, если они не принадлежат к одной и той же иерархии, даже если компилятор позволяет вам привести объект A к типу B, поскольку A не наследует от B или его наследников, вы можете вызвать один из методов типа B на брошенном объекте, и он с треском провалится во время выполнения.
class A { }
class B {
void Foo() { }
}
A a = new A();
B b = (B)a; // Compiler Error
// Hypothetically, if above was allowed, the below would ALWAYS fail at runtime
// Since there is no way the object "b" can handle this call.
b.Foo();
Здесь есть интересный момент, хотя, если B является интерфейсом, компилятор разрешил бы приведение, даже если они не принадлежат одному и тому же дереву наследования:
class A { }
interface B {
void Foo();
}
A a = new A();
B b = (B)a; // Compiler lets this happens
// Even though A does not implement B, but still one of the base classes of A
// might have implement B and A inherits that so it might be able to handle this
b.Foo();
Причина этого в том, что A может быть из другого дерева иерархии, но все еще возможно, что A или один из его базовых классов реализовали B, так что у вас может быть точка этого преобразования, и компилятор позволит это.