[英]C# Linq and lambda
Select(int.Parse)在这种Linq表达式中如何工作?
"1,2,3,4,5".Split(',').Select(int.Parse).ToList(); //ok
"1,2,3,4,5".Split(',').Select(x => int.Parse(x)).ToList(); //ok
为什么使用Console.Writeline的示例返回编译错误?
"1,2,3,4,5".Split(',').Select(Console.WriteLine).ToList(); //error
"1,2,3,4,5".Split(',').Select(x => Console.WriteLine(x)).ToList(); //ok
当允许省略像(x => ....(x))的lambda时
Console.WriteLine
和int.Parse
是所谓的方法组 。 方法组。 由于这些方法的各种重载。 它可以是一种方法,也可以是多种方法。
如果编译器可以推断该方法组中的哪个方法,则可以将方法组转换为委托。 例如,如果期望使用Func<string, int>
则方法组int.Parse
可以是int.Parse(string)
的委托。
这在您的第一个示例中有效。 Select
期望使用Func<T, T2>
并且您的T
已设置为string
类型。 但是,它不与你的第二个例子工作。 因为虽然Console.WriteLine
是方法组,但该组中没有一个方法对应于所需的Func<T, T2>
因为该组中所有方法的返回类型都是void
。
Select
的签名看起来像这样:
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector);
因此,对于selector
带有签名的方法(或lambda)
TResult Method(string s);
是期待。 Console.WriteLine()
的返回类型为void
,这不是 TResult
的有效类型 。 所以实际上两行 :
"1,2,3,4,5".Split(',').Select(Console.WriteLine).ToList();
"1,2,3,4,5".Split(',').Select(x => Console.WriteLine(x)).ToList();
不要编译 。 您确定您确实编译了第二行吗? 我的编译器的两行都引发错误CS0411 。
Select是一个投影语句,它将您的对象转换为您在Select
内指定的新对象。您需要循环并执行WriteLine:
"1,2,3,4,5".Split(',').ToList().ForEach(x=> { Console.WriteLine(x); });
Select期望参数Func<char, T>
, Console.WriteLine
不匹配。
几乎所有的LINQ扩展都接受一个返回值的函数 。 Console.WriteLine
不返回任何内容,因此不能用作参数。
"12345".Select(x => { Console.WriteLine(x); return x; }).ToList(); // this will work
"12345".Select(int.TryParse).ToList(); // this will NOT work because TryParse needs more than one parameter
"12345".ToList().ForEach(Console.WriteLine); // this will work because .ForEach accepts a method that does not return anything (void)
"12345".ToList().ForEach(int.Parse); // this will NOT work
如果方法签名与LinQ期望的相同,则允许使用此方法。
在第一种情况下, Select
的期望签名是一个方法,它带有一个string
参数,返回值是int
(或者简单地是Func<string, int>
),并且int.Parse
方法具有相同的签名,这就是为什么它起作用了;
而在第二种情况下, Console.WriteLine
的签名是一种方法,该方法具有一个string
参数,并且没有返回值(或特殊类型的返回值void
) (或简称为Action<string>
),因此没有Select
期望的签名和签名该Console.WriteLine
不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.