C# 自定义对象列表中属性列表的LINQ排序

C# 自定义对象列表中属性列表的LINQ排序,c#,linq,sorting,C#,Linq,Sorting,我有两个对象列表,每个对象都有属性推荐,它本身就是一个“推荐”对象列表。我想根据推荐对象的一个属性对其进行排序。我想到了这个: TPSqlORs.Where(x => x.Recommendations != null) .ToList() .ForEach(y => y.Recommendations.OrderBy(z => z.PointNumber)); SbmReportsORs.Where(x => x.Recommendations != n

我有两个对象列表,每个对象都有属性推荐,它本身就是一个“推荐”对象列表。我想根据推荐对象的一个属性对其进行排序。我想到了这个:

TPSqlORs.Where(x => x.Recommendations != null)
    .ToList()
    .ForEach(y => y.Recommendations.OrderBy(z => z.PointNumber));
SbmReportsORs.Where(x => x.Recommendations != null)
    .ToList()
    .ForEach(y => y.Recommendations.OrderBy(z => z.PointNumber));

但它对原始列表没有任何更改,这使我怀疑
ToList()
只是在复制,排序是在执行后丢失的副本上进行的。我沿着这些线搜索,但很明显,虽然它确实复制了一个副本,但新列表包含对原始列表元素的引用,因此它肯定应该为两个列表对它们进行排序?

OrderBy
不会改变列表的顺序。如果你想更改订单,你应该写:

y.Recommendations = y.Recommendations.OrderBy(z => z.PointNumber).ToList()

阅读关于

OrderBy
不会更改列表的顺序。如果你想更改订单,你应该写:

y.Recommendations = y.Recommendations.OrderBy(z => z.PointNumber).ToList()

阅读

OrderBy
永远不会更改原始列表的顺序。它和其他LINQ方法一样,都是纯函数。它们不修改输入,只创建新的输出。

OrderBy
永远不会更改原始列表的顺序。它和其他LINQ方法一样,都是纯函数。它们不修改输入,只创建新的输出。

大多数LINQ表达式不更改源,而是返回结果集合。

大多数LINQ表达式不更改源,它们返回一个结果集合。

因为
建议
实际上是一个
列表
您可以使用
List.sort()
对其进行适当排序:

这假设
item
是包含要排序的
建议的对象

如果列表中的
推荐
元素可以为空,则可以如下处理:

item.Recommendations.Sort
(
    (lhs, rhs) =>
    (lhs == null || rhs == null)
    ? Comparer<object>.Default.Compare(lhs, rhs) 
    : lhs.PointNumber.CompareTo(rhs.PointNumber)
);
item.Recommendations.Sort
(
(左、右)=>
(lhs==null | | rhs==null)
?比较器默认值比较(左、右)
:lhs.PointNumber.CompareTo(rhs.PointNumber)
);
有关详细信息,请参阅

请注意,
List.Sort()
是一种不稳定的排序,而
Enumerable.OrderBy()
是一种稳定的排序,但这不会对您的情况产生影响。不过,你需要意识到其中的差异


[编辑:我已将Jeppe Stig Nielsen评论中的代码合并到下面;我向他表示感谢。]

由于
建议
实际上是一个
列表
,您可以使用
List.sort()
对其进行适当排序:

这假设
item
是包含要排序的
建议的对象

如果列表中的
推荐
元素可以为空,则可以如下处理:

item.Recommendations.Sort
(
    (lhs, rhs) =>
    (lhs == null || rhs == null)
    ? Comparer<object>.Default.Compare(lhs, rhs) 
    : lhs.PointNumber.CompareTo(rhs.PointNumber)
);
item.Recommendations.Sort
(
(左、右)=>
(lhs==null | | rhs==null)
?比较器默认值比较(左、右)
:lhs.PointNumber.CompareTo(rhs.PointNumber)
);
有关详细信息,请参阅

请注意,
List.Sort()
是一种不稳定的排序,而
Enumerable.OrderBy()
是一种稳定的排序,但这不会对您的情况产生影响。不过,你需要意识到其中的差异



[编辑:我已将Jeppe Stig Nielsen评论中的代码合并到下面;我向他表示感谢。]

您可能还需要一个
ToList
电话-以避免每次访问时都重新订购,除了其他任何内容。这应该在
ForEach
中吗?如果我按照您的描述进行替换,我会被告知上下文中不存在
y
。@deed02392将您的
y.Recommendations.OrderBy(z=>z.PointNumber)
替换为行above@JonSkeet感谢您的建议:)您可能还需要一个
ToList
电话-以避免每次访问时都重新订购,除此之外。这是否应该在
ForEach
中?如果我按照您的描述进行替换,我会被告知上下文中不存在
y
。@deed02392将您的
y.Recommendations.OrderBy(z=>z.PointNumber)
替换为行above@JonSkeet感谢您的建议:)请改掉习惯,始终使用
ToList().ForEach
ToList
从第一个集合创建了一个新的集合,因此为了能够使用
List.ForEach
而不是
ForEach
会浪费cpu周期和更多内存。在这种情况下,您甚至会更加多余地使用它,因为您可以将
OrderBy
直接链接到
Where
后面。确切地说,
推荐的类型是什么?@matthewatson
List
请打破您的习惯,始终使用
ToList()。ForEach
ToList
从第一个集合创建了一个新的集合,因此为了能够使用
List.ForEach
而不是
ForEach
会浪费cpu周期和更多内存。在这种情况下,您甚至会更加多余地使用它,因为您可以将
OrderBy
直接链接到
Where
。确切地说,
推荐的类型是什么?@MatthewWatson
列表
这里是
iorderenumerable
这里是
iorderenumerable
您能说明如何最好地从您的当
项目
列表中,并且其中一些项目可能没有建议(
null
)时的体验@deed02392您的意思是
建议
本身可以为null吗?然后您可以执行类似于
(lhs,rhs)=>lhs==null | | rhs==null的操作?Comparer.Default.Compare(lhs,rhs):lhs.PointNumber.CompareTo(rhs.PointNumber)
。我假设
PointNumber
是一种不可为空的值类型?Correct@JeppeStigNielsen,谢谢您的更新。这个答案在我看来更清楚。你能说明当
项目
列表
中并且其中一些项目可能没有建议(
null
)@deed02392你的意思是
建议
本身可以为null吗?T