2008-10-01 34 views
28

Có thể thực hiện một phép đúc trong một truy vấn LINQ (vì lợi ích của trình biên dịch) không?Làm một diễn viên trong một truy vấn LINQ

Các mã sau đây không phải là khủng khiếp, nhưng nó sẽ được tốt đẹp để làm cho nó thành một truy vấn:

Content content = dataStore.RootControl as Controls.Content; 

List<TabSection> tabList = (from t in content.ChildControls 
          select t).OfType<TabSection>().ToList(); 

List<Paragraph> paragraphList = (from t in tabList 
           from p in t.ChildControls 
           select p).OfType<Paragraph>().ToList(); 

List<Line> parentLineList = (from p in paragraphList 
          from pl in p.ChildControls 
          select pl).OfType<Line>().ToList(); 

Mã này tiếp tục trên với một vài thắc mắc hơn, nhưng thực chất là tôi phải tạo ra một Liệt kê ra mỗi truy vấn để trình biên dịch biết rằng tất cả các đối tượng trong content.ChildControls thuộc loại TabSection và tất cả các đối tượng trong t.ChildControls thuộc loại Paragraph ... và cứ tiếp tục như vậy.

Có cách nào trong truy vấn LINQ để thông báo cho trình biên dịch rằng t trong from t in content.ChildControls là một TabSection?

Trả lời

25

Hãy thử điều này:

from TabSection t in content.ChildControls 

Ngoài ra, thậm chí nếu điều này không có sẵn (hoặc cho một kịch bản khác nhau, tương lai bạn có thể gặp phải), bạn sẽ không bị hạn chế để chuyển đổi tất cả mọi thứ để Lists. Việc chuyển đổi thành Danh sách sẽ đánh giá truy vấn tại chỗ. Nhưng nếu bạn loại bỏ các cuộc gọi ToList, bạn có thể làm việc với các loại IEnumerable, mà sẽ tiếp tục trì hoãn việc thực hiện truy vấn cho đến khi bạn thực sự lặp lại hoặc lưu trữ trong một container thực sự.

1

có bạn có thể làm như sau:

List<TabSection> tabList = (from t in content.ChildControls 
          where t as TabSection != null 
          select t as TabSection).ToList(); 
+0

Đó là những gì OfType () là dành cho. – Lucas

9

Tùy thuộc vào những gì bạn đang cố gắng để làm, một trong những có thể làm các trick:

List<Line> parentLineList1 = 
    (from t in content.ChildControls.OfType<TabSection>() 
    from p in t.ChildControls.OfType<Paragraph>() 
    from pl in p.ChildControls.OfType<Line>() 
    select pl).ToList(); 

List<Line> parentLineList2 = 
    (from TabSection t in content.ChildControls 
    from Paragraph p in t.ChildControls 
    from Line pl in p.ChildControls 
    select pl).ToList(); 

Lưu ý rằng ai sử dụng OfType <T>(), mà bạn đang sử dụng. Điều này sẽ lọc kết quả và chỉ trả lại các mục thuộc loại được chỉ định. Truy vấn thứ hai ngầm sử dụng Cast <T>(), sẽ đưa kết quả vào loại được chỉ định. Nếu bất kỳ mục nào không thể được đúc, một ngoại lệ được ném ra. Như đã đề cập bởi Turbulent Intellect, bạn nên tránh gọi ToList() càng lâu càng tốt, hoặc cố gắng tránh nó hoàn toàn.

1

Và đây là biểu mẫu truy vấn.

List<Line> parentLineList = 
    content.ChildControls.OfType<TabSections>() 
    .SelectMany(t => t.ChildControls.OfType<Paragraph>()) 
    .SelectMany(p => p.ChildControls.OfType<Line>()) 
    .ToList(); 
2
List<TabSection> tabList = (from t in content.ChildControls 
          let ts = t as TabSection 
          where ts != null 
          select ts).ToList(); 
+0

Đó là những gì OfType () dành cho. – Lucas

+0

Phản ánh trên OfType () đã đưa tôi đến kết luận rằng nó kém hiệu quả hơn giải pháp của tôi. –

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