2010-10-01 25 views
33

Tôi có một bộ sưu tập, trong đó có hai loại đối tượng Một & B.LINQ lựa chọn theo loại của một đối tượng

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()); 

Bây giờ tôi muốn chọn các đối tượng từ bộ sưu tập dựa trên loại của nó (A hoặc B, không phải cả hai).

Tôi có thể viết truy vấn LINQ cho điều này như thế nào? Làm ơn giúp tôi. Nếu không, tôi cần phải lặp qua bộ sưu tập mà tôi không muốn. Cảm ơn.

Chỉnh sửa:

Cảm ơn tất cả sự giúp đỡ của bạn. Bây giờ tôi có thể sử dụng OfType() từ LINQ. Nhưng tôi nghĩ trong trường hợp của tôi nó sẽ không hoạt động. Tình huống của tôi là

Class Container 
{ 
    List<Base> bases; 
} 

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

Bây giờ tôi muốn chọn vùng chứa từ các vùng chứa, có ít nhất một loại A. Có thể không thể thực hiện điều này bởi LINQ. Cảm ơn rất nhiều.

+3

Bạn có thể mở rộng chỉnh sửa của mình không? Bạn có ý gì khi "chọn vùng chứa"? –

+0

Hoặc chỉ cần tạo một câu hỏi mới .... – WoIIe

Trả lời

69

Bạn có thể sử dụng phương pháp OfType LINQ cho rằng:

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

Về sự miễn cưỡng của mình để lặp nghĩ các bộ sưu tập, bạn nên ghi nhớ rằng LINQ không làm ảo thuật; Tôi đã không kiểm tra việc triển khai OfType, nhưng tôi sẽ ngạc nhiên không phải để tìm vòng lặp hoặc trình lặp trong đó.

+0

Cảm ơn Fredrik. Tôi có thêm một câu hỏi, nếu có nhiều người trả lời đúng, câu trả lời nào tôi cần làm là "Câu trả lời đúng"? – jaks

+2

@Jai: Bạn nên đánh dấu câu trả lời mà bạn thấy hữu ích nhất hoặc hữu ích. Cả Jared và Fredrik đều đúng, nhưng câu trả lời của Fredrik có chiều sâu hơn và có thể giúp bạn tìm hiểu thêm. –

+0

@Jai: lật một đồng xu? Có một đồng xu flipper đây, nếu bạn cần một: http://www.random.org/coins/?num=1&cur=20-novelty.voting-2004 - không thể tìm thấy một đồng xu bỏ phiếu giữa tôi và @ JaredPar , vì vậy bạn sẽ phải làm với Kerry so với Bush. Tôi sẽ để nó cho bạn để quyết định ai là ai;) –

11

Bạn có thể sử dụng phương pháp mở rộng OfType cho điều này

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

Cảm ơn một tấn JaredPar. – jaks

7

Để hoàn chỉnh, đây là mã nguồn của 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; 
    } 
} 

Bạn có thể thấy rằng nó sẽ đánh giá một cách lười biếng luồng nguồn.

Các vấn đề liên quan