Рейтинг:
1
Christiaan van Bergen
Привет,
Это работает, потому что, вероятно, класс Dog является производным от класса Animal. Превращение собаки в животное.
public class Animal{}
public class Dog : Animal {}
Это значит, что в коллекцию животных мы всегда можем поместить собаку.
Все собаки-животные, но не все животные-собаки.
А теперь, если мы представим вам кошку ...
public class Cat : Animal {}
Мы также можем вставить эту кошку в коллекцию животных. Потому что это животное.
Однако мы не сможем поместить просто любое животное в коллекцию собак, потому что это означало бы, что мы могли бы просто поместить туда кошку. Вот почему нам нужно было бы бросить объект собаке, чтобы сделать это.
var dog = new Dog();
var cat = new Cat();
var animals = new List<Animal>();
animals.Add(dog); //works
animals.Add(cat); //works
var dogs = new List<Dog>();
dogs.Add(dog); //works
dogs.Add(cat); //fails
ХТ христиан
Рейтинг:
0
OriginalGriff
Предполагая, что у вас где-то есть такой код:
public class Animal { ... }
public class Dog : Animal { ... }
Тогда вы знаете, что Собака - это животное, поэтому вы можете назначить экземпляр собаки любой переменной, которая может содержать собаку или животное:
Dog dog = new Dog();
Animal animal = dog;
И вы, наверное, знаете, что-то IList&ЛТ;Т> включает в себя интерфейс IEnumerable&ЛТ;П&ГТ; среди других интерфейсов:
Интерфейс IList<T> (System.Коллекции.Общий)[
^]
Таким образом, любая переменная, которая может содержать IEnumerable<T>, может содержать экземпляр любого экземпляра класса, который ее реализует, и IList<T> это делает.
Поэтому, если подчиненный класс T также совместим, приведение не требуется, так как тип вообще не меняется.
The_Unknown_Member
Но ссылочная переменная, указывающая на список собак, - это интерфейс "IList<dog>", Поэтому я должен сделать явное приведение, чтобы назначить список ссылке IEnumerable<animal & gt;. Но на самом деле это работает??
Смотрите этот пример:
статический недействительным Главная()
{
IAnimal a = новая собака();
Кора(а);
}
статический недействительным гавкать(собака д)
{
Приставка.WriteLine("Баау баау :@@@");
}
"Bark(a);" этот код не будет работать, если я не приведу аргумент явно к Dog.
OriginalGriff
Это работает, потому что Собака - это животное, но ваш "новый код" не работает, потому что не каждое животное-Собака (некоторые могут быть кошкой, другие - лошадью).
Когда вы пишете это:
static void Bark(Dog d)
Вы говорите методу лая, что он должен принимать только параметры собаки.
Если бы ваш код работал, я мог бы сделать это:
IAnimal a = new Dog();
Bark(a);
a = new Horse();
Bark(a);
И тогда метод потерпит неудачу во время выполнения, потому что класс Horse не конвертируется в Dog (за исключением того, что он идет через "собачий корм", конечно...)
Подумайте об этом:
Если ваш метод сделал что-то специфичное для собаки с этим параметром:
static void Bark(Dog d)
{
d.Fetch(myStick);
}
и вы можете передать его любому животному, тогда что произойдет, когда вы пройдете мимо экземпляра кошки и попытаетесь научить его приносить палку?