通过使用LINQ或Lambda表达式降序子元素进行排序

时间:2019-04-28 09:22:13

标签: c# lambda foreach

我在订购List中的子元素时遇到问题,并找到了讨论List<T> vs IEnumerable<T> in foreach的主题。我想知道如何使用LINQ或Lambda Expression对子List进行订购。有人可以推荐我吗?代码示例如下:

public class Parent
{
    // Other properties...
    public IList<Child> Children { get; set; }
}

public IEnumerable<Parent> DoStuff()
{
    var result = DoOtherStuff() // Returns IEnumerable<Parent>
        .OrderByDescending(SomePredicate) 
        .ThenBy(AnotherPredicate); // This sorting works as expected in the return value.

    foreach (Parent parent in result)
    {
        parent.Children = parent.Children.OrderBy(YetAnotherPredicate).ToList();
        // When I look at parent.Children here in the debugger, it's sorted properly.
    }

    return result;
    // When I look at the return value, the Children are not sorted.
}

1 个答案:

答案 0 :(得分:1)

每次枚举result的返回IEnumerable时,您都会枚举DoStuff,并且在DoStuff本身的循环内还要再加上一个时间。但是,由于延迟执行,您不会在循环中进行的修改仍然存在:下次您枚举DoStuff()时,将再次调用DoOtherStuff等。

您可以通过几种方式解决此问题:

  • result转换为列表,然后再对子级进行排序,即

    DoOtherStuff() // Returns IEnumerable<Parent>
    .OrderByDescending(SomePredicate) 
    .ThenBy(AnotherPredicate)
    .ToList();
    
  • Select中添加子排序:

    DoOtherStuff() // Returns IEnumerable<Parent>
    .Select(parent => {
        parent.Children = parent.Children.OrderBy(YetAnotherPredicate).ToList();
        return parent;
    })
    .OrderByDescending(SomePredicate) 
    .ThenBy(AnotherPredicate)
    .ToList();
    
  • 在循环中使用yield return result(这是Select解决方案的一种变体。)