我发现了一个我完全理解的小脚本。我有一个字符串,例如“ 1 -2 5 40 ”。它读取输入字符串,将其拆分为临时数组。然后解析该数组并将每个元素转换为整数。整个过程就是将最接近的整数归零。
但我不明白的是符号 Select(int.Parse)。这里没有lambda表达式,并且不使用括号调用int.Parse方法。与 OrderBy(Math.Abs)
相同提前谢谢=)
var temps = Console.ReadLine().Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);
var result = temps.Select(int.Parse)
.OrderBy(Math.Abs)
.ThenByDescending(x => x)
.FirstOrDefault();
答案 0 :(得分:11)
int.Parse
是方法组 - 您所看到的是方法组转换为委托。要在没有LINQ的情况下看到它:
Func<string, int> parser = int.Parse;
int x = parser("10"); // x=10
这大致相当于:
Func<string, int> parser = text => int.Parse(text);
......如果您想了解详细信息,可能会有很多不同之处:)
答案 1 :(得分:5)
Select(int.Parse)
几乎相当于Select(x => int.Parse(x))
。
Select
要求Func<T, R>
,在这种情况下也是int.Parse
的签名(它有一个带有返回值的参数)。它将方法组转换为匹配的委托。
在这种情况下,Func<T, R>
将映射到Func<string, int>
,因此它与int Parse(string)
签名匹配。
答案 2 :(得分:0)
int.Parse是一个带有签名字符串的方法 - &gt; int(实际上是一个方法组,具有不同的签名。但编译器可以推断你需要这个,因为它是唯一适合的。
您可以将此方法用作参数,只要您提供具有相同签名的委托参数。
答案 3 :(得分:0)
.Select()
的参数为Func<T1, T2>()
,其中T1
是输入参数(temps
的各个值),T2
是返回类型。
通常,这是作为lambda函数编写的:x => return x + 1
等。但是,可以使用任何适合泛型定义的方法,而不必将其写为lambda,因为方法名称与赋值相同将lambda变为变量。
因此,Func<string, int> parseInt = s => Convert.ToInt32(s);
在语法上等同于调用方法int.Parse(s)
。
该语言创建了自动将Func参数传递给inside方法的快捷方式,以创建更易读的代码。
答案 4 :(得分:0)
选择LINQ IEnumerable&lt;&gt;扩展方法签名看起来像:
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector
)
查看selector
参数。在您的情况下,您将传递给具有签名的Select .Net标准函数int.Parse
:
public static int Parse(
string s
)
.Net编译器可以将代理转换为Func&lt; ...&gt;或行动&lt; ...&gt;。在int.Parse的情况下,它可以转换为Func,因此可以作为参数传递给Select方法。
与OrderBy完全相同。看看它的签名。