2012-09-20 53 views
1

嗨我有一個通用的方法,它將我在頁面上的所有html控件添加到使用一系列foreach循環工作的通用列表中,是否可以將其轉換爲linq表達式?將這一系列的foreach循環轉換爲linq表達式

private List<T> GetControls<T>() where T : HtmlControl 
     { 
      List<T> c = new List<T>(); 

      foreach (HtmlControl c1 in Controls) 
      { 
       foreach (HtmlControl c2 in c1.Controls) 
       { 
        if (c2.GetType() == typeof(HtmlForm)) 
        { 
         foreach (Control c3 in c2.Controls) 
         { 
          if (c3.GetType() == typeof(ContentPlaceHolder)) 
          { 
           foreach (HtmlControl c4 in c3.Controls) 
           { 
            if (c4.GetType() == typeof(T)) 
            { 
             c.Add((T)c4); 
            } 
            if (c4.GetType() == typeof(PlaceHolder)) 
            { 
             foreach (HtmlControl c5 in c4.Controls) 
             { 
              if (c5.GetType() == typeof(T)) 
              { 
               c.Add((T)c5); 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
      return c; 
     } 

謝謝

+0

的[遊客](http://www.oodesign.com/visitor-pattern.html)設計模式,將有助於解開代碼喜歡這個。 – Jon

+0

乾杯喬恩,應該看看它。 –

回答

1

這應做到:

List<T> c = this.Controls.Cast<Control>() 
    .SelectMany(c1 => c1.Controls.Cast<Control>()) 
    .OfType<HtmlForm>() 
    .SelectMany(c2 => c2.Controls.Cast<Control>()) 
    .OfType<ContentPlaceHolder>() 
    .SelectMany(c3 => c3.Controls.Cast<Control>()) 
    .SelectMany(c4 => 
     { 
      if (c4 is T) 
       return new[] { (T)c4 }; 
      if (c4 is PlaceHolder) 
       return c4.Controls.Cast<Control>().OfType<T>(); 
      return Enumerable.Empty<T>(); 
     }) 
    .ToList(); 

然而,n ote我在這裏使用了is而不是類型比較。這是故意的,因爲這是LINQ方法在內部也使用的。

如果你確定要確切類型,而不是通過一個is比較對象,你必須實現自己的OfType(或只使用.Where(x => x.GetType == typeof(whatever))代替。)

(另請注意,我使用Control代替HtmlControl,在某些情況下,你的HtmlControl S的含有常規Control秒)

+0

謝謝你Rawling,出色地工作 –

0

你可以嘗試這樣的事:

private List<T> GetControls<T>() where T : HtmlControl 
    { 
     List<T> c = new List<T>(); 

     foreach (HtmlControl c4 in from HtmlControl c1 in Controls 
            from HtmlControl c2 in c1.Controls 
            where c2.GetType() == typeof (HtmlForm) 
            from Control c3 in c2.Controls 
            where c3.GetType() == typeof (ContentPlaceHolder) 
            from HtmlControl c4 in c3.Controls 
            select c4) 
     { 
      if (c4.GetType() == typeof(T)) 
      { 
       c.Add((T)c4); 
      } 
      if (c4.GetType() == typeof(PlaceHolder)) 
      { 
       c.AddRange(from HtmlControl c5 in c4.Controls where c5.GetType() == typeof (T) select (T) c5); 
      } 
     } 
     return c; 
    } 

雖然我不知道它的任何更優雅......

+0

感謝您的貢獻RedEyedMonster,雖然這似乎引發InvalidCastException。 –