从IEnumerable中选择时,避免重复自己

时间:2015-03-17 15:25:23

标签: c# linq lambda xelement

我有IEumerable<XElement>名为foo

我有这段代码

foo.Select(x => new
        {
            bars = x.Descendants(namespace + "bar") != null 
                ? x.Descendants(namespace + "bar").Select(z => z.Value).ToArray() 
                : new string[0]
        })
        .ToArray();

我怎么能写一点整洁?我真的不想重复这一部分

x.Descendants(namespace + "bar")

3 个答案:

答案 0 :(得分:3)

使用额外的Select

foo.Select(x => x.Descendants(namespace + "bar"))
   .Select(x => new
            {
                bars = x != null ? x.Select(z => z.Value).ToArray() : new string[0]
            })
            .ToArray();

或者:

foo.Select(x =>
               {
                   var elements = x.Descendants(namespace + "bar");
                   return new
                   {
                      bars = elements != null ? elements.Select(z => z.Value).ToArray() : new string[0]
                   }
                })
            .ToArray();

BTW ,我认为Descendants不会返回 null 。您应该使用Any方法检查是否有任何元素。

 bars = x.Any() ? x.Select(z => z.Value).ToArray() : new string[0]

答案 1 :(得分:1)

您可以使用不同的lambda表达式来避免重复,如下所示,您还可以实现空检查。

Function<XElement,IEnumerable<XElement>> f =
    x =>  x.Descendants(namespace + "bar") ?? Enumerable.Empty<XElement>():

foo.Select(x => new 
            {
                f(x).Select(z => z.Value).ToArray();
            })
            .ToArray();

答案 2 :(得分:1)

foo.Select(x => new
    {
        bars = x.Descendants(namespace + "bar") != null 
            ? x.Descendants(namespace + "bar").Select(z => z.Value).ToArray() 
            : new string[0]
    })
    .ToArray();
  

我怎么能写一点整洁?我真的不想重复   这部分

foo.Select(x => new { bars = x.Descendants(namespace + "bar")
                              .Select(z => z.Value).ToArray()}).ToArray();

你不需要检查NULL,因为后代返回一个延迟的可枚举,例如,它将始终有一个IEnumerable的实例,它可能是空的(没有结果),但是 .Select(z =&gt; z.Value)。如果没有结果,.ToArray()会自动生成新的字符串[0] {}