繁体   English   中英

Lambda和类型推断

[英]Lambdas and type inference

我在理解以下代码导致我出现错误的原因时遇到了一些麻烦:

 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>>或通过使用辅助方法,例如private static Func<T1, TR> MakeFunc<T1, TR>(Func<T1, TR> f) { return f; }并使用Select(x => MakeFunc(y => x + y))

但是,我想了解编译器无法推断类型的原因。 到目前为止,我最好的猜测是,根据7.15.6,它无法确定是否应该将内部lambda转换为Func或Expr。 我是对的还是其他内容?

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

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

原因很简单:

编译如何得出结论应该是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);

一个小好处:您可以将int放在y之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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