我找到了一个我完全理解的小脚本。例如,我有一个带有
*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();
int.Parse
是一个 方法组 - 您看到的是方法组到委托的转换。要在不使用 LINQ 的情况下查看它:
Func<string, int> parser = int.Parse;
int x = parser("10"); // x=10
它主要相当于:
Func<string, int> parser = text => int.Parse(text);
...尽管如果您想详细了解的话,会有很多差异:)
Select(int.Parse)
几乎等同于 Select(x => int.Parse(x))
。
Select
需要一个Func<T, R>
,在本例中也是int.Parse
的签名(它有一个带有返回值的参数)。它将方法组转换为匹配的委托。
在这种情况下,
Func<T, R>
将映射到Func<string, int>
,因此它与int Parse(string)
签名匹配。
.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 参数传递给内部方法的快捷方式,以创建更具可读性的代码。
int.Parse 是一个签名为 string -> int 的方法(或者实际上是一个方法组,具有不同的签名。但是编译器可以推断你需要这个,因为它是唯一适合的。
无论您在何处提供具有相同签名的委托参数,都可以使用此方法作为参数。
选择 LINQ IEnumerable<> 扩展方法签名如下所示:
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<...> 或 Action<...>。对于 int.Parse,它可以转换为 Func,因此可以作为参数传递给 Select 方法。
与 OrderBy 完全相同。也看看它的签名。