c# – Lambdas和类型推断

我在理解以下代码为什么会给我一个错误的原因时遇到一些麻烦:

 var funs = Enumerable.Range(0, 10).Select(x => (int y) => x + y);
 foreach (var fun in funs)
   Console.WriteLine("{0}", fun(10));

错误是“无法使用’System.Collections.Generic.IEnumerator.Current’”初始化隐式类型的局部变量声明.我知道如何修复它(通过指定要选择的类型,例如Select< int,Func< int,int>>或者使用辅助方法,例如私有静态Func< T1,TR> MakeFunc< T1,TR> ;(Func< T1,TR> f){return f;}并使用Select(x => MakeFunc(y => xy)).

但是,我想了解编译器无法推断出类型的原因.到目前为止,我最好的猜测是,根据7.15.6,它无法弄清楚它是否应该将内部lambda转换为Func或Expr.我是正确还是还有更多内容?

作为参考,这是7.15.6所说的:

“必须始终将匿名函数F转换为委托类型D或表达式树类型E,直接或通过执行委托创建表达式new D(F).此转换确定匿名函数的结果.”

最佳答案 原因很简单:

编译如何得出结论:它应该是Func< int,int>?他简单不了!

假设您有自己的委托:

 public delegate int F(int i);

编译器如何在Func< int,int>之间进行选择?而F?这些是完全不同的类型,有两个共同点:有两个委托并具有相同的签名(一个参数和返回类型,都是int类型).

所以编译器无法选择;你将不得不这样做:

var funs = Enumerable.Range(0, 10).Select<int, Func<int,int>>(x => y => x + y);

要么

var funs = Enumerable.Range(0, 10).Select<int, F>(x => y => x + y);

一个小优点:你可以在y之前删除int.

点赞