1

首先运行以下代码

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.OrderBy(i => --i);

            foreach (var i in ordered)
            {
                Console.WriteLine(i);
            }

输出:和之前一样

我的问题是为什么会这样??

4

3 回答 3

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);
于 2013-04-24T17:27:58.540 回答
4

您示例中的变量i不是列表中项目的别名,它实际上是列表中该项目的值的副本。改变该副本不会改变序列本身中的项目。

请注意,按照设计,LINQ 操作应避免对它们所采用的委托造成副作用。它们是为查询序列而设计的,因此它们不应该改变序列本身。LINQ 编程“风格”会说您应该创建一个新序列,该序列基于您拥有的列表,但每个项目都略有更改。这称为“投影”,使用以下Select方法完成:

var newList = list.Select(i => i + 1)
    .OrderBy(i => i);
于 2013-04-24T17:29:11.577 回答
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

于 2013-04-24T17:37:47.093 回答