Подтвердить что ты не робот

Как преобразовать List <interface> в List <concrete>?

У меня есть интерфейс, определяемый как:

public interface MyInterface {
     object foo { get; set; };
}

и класс, реализующий этот интерфейс:

public class MyClass : MyInterface {
     object foo { get; set; }
}

Затем я создаю функцию, которая возвращает ICollection следующим образом:

public ICollection<MyClass> Classes() {
    List<MyClass> value;

    List<MyInterface> list = new List<MyInterface>(
        new MyInterface[] {
            new MyClass {
                ID = 1
            },
            new MyClass {
                ID = 1
            },
            new MyClass {
                ID = 1
            }
        });

    value = new List<MyClass>((IEnumerable<MyClass>) list);

    return value;
}

Он скомпилировал бы, но выбрал бы

Невозможно запустить объект типа 'System.Collections.Generic.List 1[MyInterface]' to type 'System.Collections.Generic.IEnumerable 1 [МойКласс]'.

исключение. Что я делаю неправильно?

4b9b3361

Ответ 1

A List<MyInterface> не может быть преобразован в List<MyClass> вообще, потому что в первом списке могут быть объекты, реализующие MyInterface, но не являющиеся фактически объектами типа MyClass.

Однако, поскольку в вашем случае вы знаете, как вы создали список, и можете быть уверены, что он содержит только объекты MyClass, вы можете сделать это с помощью Linq:

return list.ConvertAll(o => (MyClass)o);

Ответ 2

Но a List<MyInterface> категорически не является List<MyClass>.

Думай:

interface IAnimal { }

class Cat : IAnimal { }
class Dog : IAnimal { }

var list = new List<IAnimal> { new Cat(), new Dog() };

Тогда

var cats = (List<Cat>)list;

Абсурд!

Кроме того,

var cats = list.Cast<Cat>();

Абсурд!

Далее

var cats = list.ConvertAll(x => (Cat)x);

Абсурд!

Вместо этого вы можете сказать

var cats = list.OfType<Cat>();

Ответ 3

Я нахожу Automapper очень полезным для преобразования интерфейсов в конкретные классы.