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