C# 符号理解:Select(int.Parse)

8

我找到了一个我完全理解的小脚本。例如,我有一个字符串"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();
5个回答

12

int.Parse 是一个方法组 - 你所看到的是将方法组转换为委托。如果不使用 LINQ,可以这样看:

int.Parse 是一组方法 - 您所看到的是将该组方法转换成委托。要在没有 LINQ 的情况下查看它:

Func<string, int> parser = int.Parse;
int x = parser("10"); // x=10

它大体上等同于:

Func<string, int> parser = text => int.Parse(text);

...虽然如果你想深入细节,还是有很多区别的 :)


7

Select(int.Parse) 几乎等同于 Select(x => int.Parse(x))

Select 要求一个 Func<T, R>,在这种情况下也是 int.Parse 的签名(它具有一个参数和一个返回值)。它将方法组转换为匹配的委托。

在此情况下,Func<T, R> 将映射到 Func<string, int>,因此它与 int Parse(string) 签名匹配。


1

.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 参数传递给内部方法以创建更可读代码的快捷方式。


0

选择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也完全相同。看一下它的签名。


0

int.Parse是一个方法,其签名为string -> int(实际上是一个方法组,具有不同的签名。但编译器可以推断出您需要这个方法,因为它是唯一适合的方法)。

您可以在任何提供具有相同签名的委托参数的地方使用此方法作为参数。


这并没有解释为什么你可以像这样使用它。 - Panagiotis Kanavos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接