2008-10-01 24 views
28

Czy można wykonać rzutowanie w zapytaniu LINQ (dla samego kompilatora)?Wykonywanie rzutowania wewnątrz kwerendy LINQ

Poniższy kod nie jest straszna, ale byłoby miło, aby go w jednym zapytaniu:

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

Kod kontynuuje się jeszcze kilka pytań, ale sens jest muszę utworzyć Wypisz z każdego zapytania, aby kompilator wiedział, że wszystkie obiekty w content.ChildControls są typu TabSection, a wszystkie obiekty w t.ChildControls są typu Paragraph ... i tak dalej i tak dalej.

Czy istnieje sposób wewnątrz kwerendy LINQ, aby poinformować kompilator, że t w from t in content.ChildControls jest TabSection?

Odpowiedz

25

Spróbuj tego:

from TabSection t in content.ChildControls 

Ponadto, nawet jeśli nie były dostępne (lub innego, przyszłego scenariusza można spotkać), nie będzie ograniczone do konwersji wszystko do list. Konwersja na listę powoduje ewaluację zapytań na miejscu. Ale jeśli usuniesz wywołanie ToList, możesz pracować z typem IEnumerable, który będzie nadal odraczał wykonywanie zapytania do momentu, aż faktycznie wykonasz iterację lub przechowywanie w rzeczywistym kontenerze.

1

tak można wykonać następujące czynności:

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

To co OfType () jest za. – Lucas

9

W zależności od tego, co staramy się robić, jedna z nich może rade:

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

Zauważ, że ktoś używa OfType <T>(), z którego korzystałeś. Spowoduje to przefiltrowanie wyników i zwrócenie tylko elementów określonego typu. Drugie zapytanie domyślnie używa Cast <T>(), który rzuca wyniki na określony typ. Jeśli dowolny element nie może być rzutowany, zostanie zgłoszony wyjątek. Jak wspomniano w Burzliwym Intelektu, powinieneś powstrzymać się od wywoływania ToList() tak długo, jak to możliwe, lub próbować całkowicie tego uniknąć.

1

A oto formularz formularza zapytania.

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

Do tego służy OfType (). – Lucas

+0

Refleksja nad TypeType () doprowadziła mnie do wniosku, że jest mniej wydajny niż moje rozwiązanie. –

Powiązane problemy