对于熟悉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;这里发生了什么?
答案 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”是一个只返回一个输入值的函数的技术术语。)
是。他们可以。他们没有,可能是因为他们只是不认为值得花时间/精力,因为编写一个身份函数很容易,没有任何特殊的语法。