难以理解特定的lambda表达式

时间:2013-05-30 17:52:02

标签: c# linq lambda

对于熟悉lambda的人来说,这是一个非常简单的问题。我现在正在学习它,并遇到了一个对我没有意义的表达。

据我所知,lambda表达式传入左侧指定的变量并运行右侧的代码。例如

myFunction = x => x + x;

所以myFunction(2)将返回4.

无论如何,我在这里看了一个linq查询并看到了这个:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

n => n ......那是做什么的?为什么不说OrderBy(n)?你正在做的就是将n传递给一个只返回n的函数。 &GT; _&GT;这里发生了什么?

3 个答案:

答案 0 :(得分:9)

  

n => n ......那会怎么做?

它只是将任何值映射到自身。这是一种身份功能。

  

为什么不说OrderBy(n)?

因为n不是范围内的变量 - 所以调用它是无效的。这不是lambda表达式,因此它只会尝试使用n作为普通方法参数。

你的代码 只是试图说“按每个元素的整个顺序排序”而不是将每个元素投射到其他值,但是没有办法直接说出来。

OrderBy 需要从元素类型到排序键类型的投影 - 这只是在这种情况下我们需要身份投影。

您可以编写自己的额外扩展方法:

public static IEnumerable<T> OrderNaturally<T>(this IEnumerable<T> source)
{
    return source.OrderBy(item => item);
}

然后将原始陈述更改为:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderNaturally();

如果您发现更具可读性。

或者,您可以使用一些有用的静态只读字段创建Functions类:

public static class Functions<T>
{
    public static readonly Func<T, T> Identity = x => x;
    public static readonly Func<T, T> DefaultValue => x => default(T);
    public static readonly Func<T, string> ToString = x => x == null ? null : x.ToString();
    ...
}

然后:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0)
                                    .OrderBy(Functions<int>.Identity)

我不认为我这样做......我只是在暗示要考虑的事情:)

答案 1 :(得分:4)

让我们打破这个:

numbers

这是integers

的集合
.Where(num => num % 2 == 0)

这就是说“在我的收藏中找到我的数字模数2 = 0”的所有项目。

.OrderBy(n => n);

然后订购列表。因为列表是整数,并且指定的项是整数,所以它将按数字排序,从最低到最高。

您需要n => n的原因是因为您可以按值之外的其他内容进行排序。例如,将项目的长度称为字符串

.OrderBy(n => n.ToString().Length)

显然,对于整数来说,这没有任何意义。但是对于其他数据类型,比如类,这非常有用。

答案 2 :(得分:0)

n => n表示函数接受一个参数作为输入,并将其输入作为返回值返回。

  

为什么不说OrderBy(n)

你怎么知道n是一个lambda?有什么迹象表明它是一种功能?如果你有一个名为n的函数,它接受一个整数并返回相同的整数,那么你可以这样做,但我的猜测是你不在想的。

我知道你没有问过但是:

  

C#编译器团队是否可以用一些替代语法来涵盖“身份lambda”的特殊情况?

(“identity lambda”是一个只返回一个输入值的函数的技术术语。)

是。他们可以。他们没有,可能是因为他们只是不认为值得花时间/精力,因为编写一个身份函数很容易,没有任何特殊的语法。