繁体   English   中英

C#Linq和Lambda

[英]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.WriteLineint.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM