приведение типа к другому типу в C # - PullRequest
3 голосов
/ 07 марта 2019

Я новичок в ООП, просто у меня вопрос по кастингу, скажем, у нас есть:

interface Animal
{
   string speak();
}

class Dog : Animal
{
   public string speak()
   {
       return "wan-wan";
   }
}

class Cat : Animal
{
   public string speak()
   {
     return "miao";
   }

   public void catchMouseS()
   {
      ...
   }
}

class Program
{
   static void Main(string[] args)
   {
     Animal generic= new Dog();
     Cat cutie = (Cat)generic;   
    }
}

, чтобы вы могли видеть, что я могу напечатать собаку за кошкой, компилятор в порядкес этим, разве компилятор не должен быть достаточно умен, чтобы выдавать ошибку, потому что он наверняка столкнется с ошибкой во время выполнения, когда cutie вызывает метод catchMouses, поскольку cutie на самом деле является собакой, у которой нет метода catchMouses?

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Так работает полиморфизм и интерфейсы в .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;
}

Оба являются ссылочными типами , оба могут быть преобразованы в объект , и оба преобразования, по-видимому, возможны, поэтому он думает, что вы знаете, что делаете во время компиляции, очевидно, хотя проверки во время выполнения не пройдены.

0 голосов
/ 07 марта 2019

Случай, который вы описали, называется downcasting и считается неверным кодом по той причине, которую вы упомянули. Это разрешено во время компиляции, и происходит сбой (или неправильная работа) во время выполнения (или нет).

Вы также можете перехватить InvalidCastException и что-то с ним сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...