我在订购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.
}
答案 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
解决方案的一种变体。)