Так работает полиморфизм и интерфейсы в .Net
.
Компилятор может статически анализировать Type Reference , но он не копается во время выполнения Type объекта в памяти. Он знает достаточно, чтобы знать, что эти два типа реализуют один и тот же контракт и может сделать явное преобразование , и это хорошо для этого по веским причинам.
Теперь, для нас и для вас это очевидное Dog
- это не Cat
, мы можем увидеть его в полном наборе кода, но компилятор не пытается выяснить этот тип проблемы во время компиляции , Вы могли бы представить, что если бы у вас был миллион строк кода, он должен был бы проверить миллиарды (если не триллионы) путей разработки, если то, что вы делаете, правильно ... Все, что он знает во время компиляции, это Тип при приведении действителен (не то, что вы пытаетесь сделать с ним), и преобразование возможно.
Итак, чтобы сэкономить время на том, что действительно является огромной проблемой с большим количеством степеней свободы, (компилятор) выполняет базовую Статическую проверку , чтобы увидеть, возможно ли преобразование, и позволяет вам запутать его, однако он все еще выполняет проверку во время выполнения.
Вот еще один способ обмануть компилятор
class Dog
{
}
class Cat
{
}
public static void Main()
{
Dog d = new Dog();
var a = (object)d;
Cat cutie = (Cat)a;
}
Оба являются ссылочными типами , оба могут быть преобразованы в объект , и оба преобразования, по-видимому, возможны, поэтому он думает, что вы знаете, что делаете во время компиляции, очевидно, хотя проверки во время выполнения не пройдены.