2011-02-28 60 views
0

我有一些像這樣的代碼:如何格式化複雜的鏈式Linq語句以實現可讀性?

var effects = xElement.Elements ("Effects").Elements ("Effect").Select (
    e => new Effect (
     (EffectType) Enum.Parse (typeof (EffectType), (string) e.Elements ("Type").FirstOrDefault ()), 
     e.Elements ("Options").Any () 
      ? e.Elements ("Options").Select (o => (object) o.Elements ("Option").Select (n => n.Value).First ()) 
      : null)) 
      .ToList (); 

但目前這看起來並不爲可讀,我不知道我應該添加一個新行和/或縮進可讀性。

任何建議,我可以用來使一致的,可讀的linq塊?

+0

這是我的評論;不要使用LINQ,因爲通過每個元素的簡單循環會更清晰,抓取屬性,然後將新對象添加到列表中。 – 2011-02-28 23:18:10

+0

謝謝,能否請您舉個例子。我不知道你如何以相同的方式完成循環。 – 2011-02-28 23:20:27

回答

3

完全主觀的問題,甚至不知道爲什麼,我回答,但這裏是看起來更具可讀性

var effects = xElement 
    .Elements("Effects") 
    .Elements("Effect") 
    .Select(e => 
     new Effect(
      (EffectType)Enum.Parse(
       typeof(EffectType), 
       (string)e.Elements("Type").FirstOrDefault() 
      ), 
      e.Elements("Options").Any() 
       ? e.Elements("Options").Select(
        o => o.Elements("Option").Select(n => n.Value).First() 
       ) 
       : null 
     ) 
    ) 
    .ToList(); 

,或者如果你喜歡的查詢語法:

var effects = 
    from e in xElement.Elements("Effects").Elements("Effect") 
    let effectType = 
     (EffectType)Enum.Parse(
      typeof(EffectType), 
      (string)e.Elements("Type").FirstOrDefault() 
     ) 
    let options = 
     e.Elements("Options").Any() 
      ? e.Elements("Options").Select(
        o => o.Elements("Option").Select(n => n.Value).First() 
      ) 
      : null 
    select new Effect(effectType, options); 
+1

謝謝,很高興你回答,因爲這看起來更具可讀性。 – 2011-02-28 23:19:39

+0

這是我會寫的,幾乎完全是 – 2011-02-28 23:23:45

+0

這看起來不錯,但現在我想爲什麼它使用.Elements(「效果」),.Elements(「效果」),而不是元素(「選項「),元素(」選項「)? – 2011-02-28 23:27:43

1

改爲使用查詢表達式。我認爲它會更具可讀性。

+0

謝謝,你可以請示例,因爲我不能寫出最優雅的查詢語法。 – 2011-02-28 23:21:19

1

我認爲我會格式化是這樣的:

var effects = 
    xElement.Elements("Effects").Elements("Effect") 
    .Select (
    e => new Effect(
     (EffectType)Enum.Parse(
     typeof(EffectType), 
     (string)e.Elements("Type").FirstOrDefault() 
    ), 
     e.Elements("Options").Any() ? 
     e.Elements("Options") 
     .Select(o => (object)o.Elements("Option") 
     .Select(n => n.Value).First()) 
     : null 
    ) 
) 
    .ToList(); 
3

我喜歡小的功能有明確的名稱。類似這樣的:

public void Parse() 
    { 
     //XElement xElement = blah... 

     var elements = xElement.Elements("Effects").Elements("Effect"); 
     var converted = elements.Select(ConvertToEffect); 
    } 

    private static Effect ConvertToEffect(XElement e) 
    { 
     var value = ConvertEnum((string) e.Elements("Type").FirstOrDefault()); 
     var option = GetOption(e.Elements("Options")); 

     return new Effect(value, option); 
    } 

    private static EffectType ConvertEnum(string value) 
    { 
     return (EffectType)Enum.Parse(typeof(EffectType), value); 
    } 

    private static IEnumerable<object> GetOption(IEnumerable<XElement> e) 
    { 
     var any = e.Elements("Options").Any(); 
     if (any) 
     { 
      return e.Elements("Options").Select(o => (object) o.Elements("Option").Select(n => n.Value).First()); 
     } 

     return null; 
    }