Как мне преобразовать список <interface>в список <concrete>? - PullRequest
35 голосов
/ 16 мая 2011

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

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 [MyClass].

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

Ответы [ 4 ]

52 голосов
/ 16 мая 2011

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

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

return list.ConvertAll(o => (MyClass)o);
32 голосов
/ 16 мая 2011

Но 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>();
1 голос
/ 02 августа 2018

Вы можете использовать Cast<> метод расширения:

return list.Cast<MyClass>();
0 голосов
/ 02 июля 2015

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

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