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] 中不起作用?
最佳答案
关于类型的所有信息都不是事先已知的。在您的第一个工作代码段中,您在两行中都告诉它您希望将 s => s.Substring(n)
转换为哪种委托(delegate)类型。
在您的第二个代码段中,唯一存在该信息的地方是 Select
的结果的赋值......并且没有用作部分当编译器计算出 Select
调用本身的含义时的重载和类型推断。
所以选项是:
- 分两步完成,使用
f2
- 在
Select
调用中转换 lambda 表达式,或根据您的代码段使用new
运算符 直接为
Select
提供类型参数:var fs = numbers.Select<int, Func<string, string>>(n => s => s.Substring(n));
关于c# - IEnumerable<Func<T,S>> 和 LINQ 类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27620697/