2010-10-01 2 views
33

У меня есть коллекция, которая содержит два типа объектов A & B.выбор LINQ по типу объекта

Class Base{} 
Class A : Base {} 
Class B : Base {} 

List<Base> collection = new List<Base>(); 
collection.Add(new A()); 
collection.Add(new B()); 
collection.Add(new A()); 
collection.Add(new A()); 
collection.Add(new B()); 

Теперь я хочу, чтобы выбрать объекты из коллекции на основании его типа (А или В, не оба).

Как я могу написать запрос LINQ для этого? Пожалуйста, помогите мне. В противном случае мне нужно пройти через коллекцию, которую я не хочу. Благодарю.

Редактировать:

Благодарим всех вас за помощь. Теперь я могу использовать OfType() из LINQ. Но я думаю, что в моем случае это не сработает. Моя ситуация

Class Container 
{ 
    List<Base> bases; 
} 

List<Container> containers = new List<Container>(); 

Теперь я хочу, чтобы выбрать контейнер из контейнеров, который имеет по меньшей мере один тип A. Может быть это не может быть сделано LINQ. Большое спасибо.

+3

Не могли бы вы расширить свое редактирование? Что вы подразумеваете под «select the container»? –

+0

Или просто создайте новый вопрос .... – WoIIe

ответ

69

Вы можете использовать OfType метод Linq для этого:

var ofTypeA = collection.OfType<A>(); 

Что касается вашего нежелания цикла Повсеместно коллекции, вы должны иметь в виду, что Linq не делает фокусы; Я не проверял реализацию OfType, но я был бы удивлен не, чтобы найти там петлю или итератор.

+0

Спасибо Fredrik. У меня есть еще один вопрос, если правильно ответили несколько человек, и какой ответ мне нужно сделать как «Правильный ответ»? – jaks

+2

@Jai: Вы должны отметить ответ, который вы считаете наиболее полезным или полезным. И Джаред, и Фредрик верны, но ответ Фредрика был более глубоким и мог помочь вам узнать больше. –

+0

@Jai: перевернуть монету? Здесь есть монета-флиппер, если вам это нужно: http://www.random.org/coins/?num=1&cur=20-novelty.voting-2004 - не удалось найти монеты для голосования между мной и @JaredPar , так что вам придется делать с Керри против Буша. Я оставлю это вам, чтобы решить, кто есть кто:) –

11

Вы можете использовать метод расширения OfType для этого

IEnumerable<A> filteredToA = list.OfType<A>(); 
IEnumerable<B> filteredToB = list.OfType<B>(); 
+0

Спасибо за тонну JaredPar. – jaks

7

Для полноты картины, вот исходный код Enumerable.OfType<T>.

public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) { 
    if (source == null) throw Error.ArgumentNull("source"); 
    return OfTypeIterator<TResult>(source); 
} 

static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) { 
    foreach (object obj in source) { 
     if (obj is TResult) yield return (TResult)obj; 
    } 
} 

Вы можете видеть, что он лениво оценивает исходный поток.

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