C#编译器可以正确推断这些片段中的s(字符串)类型:
Func<int, string, string> f1 = (n, s) => s.Substring(n);
Func<int, Func<string, string>> f2 = n => s => s.Substring(n);
但它不能在这一个[1]:
var numbers = Enumerable.Range(1, 10);
IEnumerable<Func<string, string>> fs = numbers.Select(n => s => s.Substring(n));
要使其工作,必须做这样的事情:
var fs = numbers.Select(n => new Func<string, string>(s => s.Substring(n));
或
var fs = numbers.Select(f2);
问题是 - 如果预先知道关于类型的所有必要信息,为什么类型推断在[1]中不起作用?
答案 0 :(得分:7)
预先知道类型的所有信息。在您的第一个工作代码段中,您将在两行中告诉它要将s => s.Substring(n)
转换为委托类型。
在您的第二个代码段中,唯一存在该信息的地方是Select
的结果的分配...并且不会将其用作重载的一部分当编译器计算Select
调用本身意味着什么时,键入推断。
所以选项是:
f2
Select
来电中投放lambda表达式,或根据您的代码段使用new
运算符直接提供Select
的类型参数:
var fs = numbers.Select<int, Func<string, string>>(n => s => s.Substring(n));