从 IEnumerable 执行 Select 时避免重复自己

Avoid Repeating Oneself When Doing A Select From IEnumerable

我有一个名为 fooIEumerable<XElement>

我有这个代码

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")

使用额外的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 会 return null。你应该检查是否有任何元素使用 Any 方法。

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

您可以使用不同的 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();
foo.Select(x => new
    {
        bars = x.Descendants(namespace + "bar") != null 
            ? x.Descendants(namespace + "bar").Select(z => z.Value).ToArray() 
            : new string[0]
    })
    .ToArray();

How can I write this a little neater? I really don't want to repeat this part

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

您不需要检查 NULL 作为 Descendants returns 一个延迟的可枚举,例如,它总是有一个 IEnumerable 的实例,它可能是空的(没有结果),但是 .Select(z => z.Value).ToArray() 会自动产生新的 string[0] { } 如果有没有结果。