2013-07-24 3 views
0

У меня есть List<> абстрактных объектов, содержащих различные типы объектов. Я пытаюсь захватить все предметы определенного типа и установить эти предметы самостоятельно List<>.Получить все элементы определенного типа из списка абстрактного типа

Это не работает -

//myAbstractItems is a List<myAbstractItem> 
//typeAList inherents from myAbstractItem 


var typeAList = ((List<itemTypeA>)myAbstractItems.Where(i => i.GetType() == typeof(itemTypeA)).ToList()); 

Отливка (List<itemTypeA>) кажется, терпит неудачу.

+0

Важно ли, если вы получаете элементы типа 'itemTypeA' или производный тип_ или получаете элементы' itemTypeA' _exactly_? –

ответ

5

Используйте OfType extension method:

var typeAList = myAbstractItems.OfType<itemTypeA>().ToList(); 

Из документации ...

Метод OfType (IEnumerable) возвращает только те элементы в источник, который может быть отлит для ввода TResult.

+0

Отличный ответ BACON! Благодаря! –

+0

Просто для полноты это решение имеет следующие (хорошие) свойства: ** (1) ** Элементы типа _derived_ из 'itemTypeA' также включены в новый список. (Здесь 'itemTypeA', как известно, является классом типа. Если бы это был общий тип интерфейса, общий тип делегата или тип массива, co- и/или контравариантность также были рассмотрены.) ** (2) ** Любые «нулевые» записи не имеют типа времени выполнения: _not_ включены в новый список. –

0

Попробуйте использовать Where таким образом:

var typeAList = myAbstractItems.Where(i => i.GetType() == typeof(itemTypeA)).Select(item => item as itemTypeA).ToList()) 
+0

Вместо последнего 'Select' вы _could_ также выполняете' .Cast () '. –

0

старый добрый цикл должен быть в порядке:

List<itemTypeA> res = new List<itemTypeA>(); 
foreach(var item in myAbstractItems) 
{ 
    itemTypeA temp = item as itemTypeA; 
    if (temp != null) 
    res.Add(temp) 
} 
+1

Это тонко отличается от (предпринятого) исходного кода тем, что он вернет все, что может быть назначено как «itemTypeA», а не только вещи этого * точного * типа. – Rawling

+0

Вы правы, но код и вопрос неоднозначны в вопросе ^^ –

+0

Да, извинения, я хотел добавить в свой комментарий, что ваша версия вполне может быть тем, что хочет OP *: p – Rawling

0

Это будет работать для всех itemTypeA s (и более производных типов).

var typeAList = myAbstractItems.Select(i => i as itemTypeA).Where(i => i != null).ToList(); 

EDIT: отредактировано в соответствии с комментарием Ролинг.

+1

Почему бы не поставить 'Select' перед' Where' и не выполнять букву 'as' дважды? – Rawling

0

Другим способом вы могли бы сделать это с помощью OfType() метод:

var typeAList = myAbstractItems.OfType<itemTypeA>().ToList(); 

Этот способ в основном выполняет следующие операции:

var typeAList = myAbstractItems.Where(i=>i is itemTypeA).Select(i=>i as itemTypeA).ToList(); 

Имейте в виду, что это не сработает, если какой-либо элемент исходной коллекции является нулевой ссылкой.

+0

Последний пример привел бы «Список », а не «Список », об этом говорит «Оригинальный плакат».Интересно помнить, что происходит с элементами «null». –

+0

Отредактировано. Спасибо что подметил это. – KeithS

Смежные вопросы