首先运行以下代码
var list = new List<int> {1, 5, 0, 65, 2, 1, 0, 10};
var ordered = list.OrderBy(i => ++i);
foreach (var i in ordered)
{
Console.WriteLine(i);
}
输出:0 0 1 1 2 五 10 65
然后,
var list = new List<int> {1, 5, 0, 65, 2, 1, 0, 10};
var ordered = list.OrderBy(i => --i);
foreach (var i in ordered)
{
Console.WriteLine(i);
}
输出:与之前相同
我的问题是为什么会发生这种情况?
答案 0 :(得分:10)
我的问题是为什么会发生这种情况?
您的第二种形式实际上与:
相同var ordered = list.OrderBy(i => i - 1);
...除非你的值为Int32.MinValue
,否则不会改变排序。
在lambda表达式中更改参数的值这一事实无关紧要 - 之后有效地抛弃了该参数值。它不会更改序列中的值。如果您想要输出-1 -1 0 0 1 4 9 64,那么您应该使用:
var ordered = list.Select(i => i - 1).OrderBy(i => i);
答案 1 :(得分:4)
示例中的变量i
不是列表中项目的别名,它实际上是列表中该项目值的副本。变异该副本不会改变序列本身的项目。
请注意,根据设计,LINQ操作应避免对其所采用的委托造成副作用。它们是为查询序列而设计的,因此它们不应该改变序列本身。编程的LINQ“风格”会说你应该创建一个基于你所拥有的列表的新序列,但是每个项目都会略有改变。这称为“投影”,使用Select
方法完成:
var newList = list.Select(i => i + 1)
.OrderBy(i => i);
答案 2 :(得分:1)
也许你期望按负值排序所有东西(有效地扭转排序)?在这种情况下,您可以使用OrderByDescending
:
var list = new List<int> {1, 5, 0, 65, 2, 1, 0, 10};
var ordered = list.OrderBy(i => i);
foreach (var i in ordered)
{
Console.WriteLine(i);
}
输出:0 0 1 1 2 5 10 65
var list = new List<int> {1, 5, 0, 65, 2, 1, 0, 10};
var ordered = list.OrderByDescending(i => i);
foreach (var i in ordered)
{
Console.WriteLine(i);
}
输出:65 10 5 2 1 1 0 0
++
和--
分别将变量的值更改为加号或减号1。它们不会改变变量的符号。
int x = 5;
--x;
执行上述操作后,x
的值为4
。