【问题标题】:Lambdas and type inferenceLambda 和类型推断
【发布时间】:2013-05-19 15:58:30
【问题描述】:

我在理解以下代码给我错误背后的原因时遇到了一些麻烦:

 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 必须始终转换为委托类型 D 或表达式树类型 E,直接或通过执行委托创建表达式 new D(F)。这种转换决定了匿名函数的结果。”

【问题讨论】:

  • 尝试将返回的 lambda 封装在代码块中,看看会发生什么?
  • 这可能会有所帮助:stackoverflow.com/a/4966409/1223622
  • 谢谢 Ben,看来我走在了正确的轨道上,除非它知道将其转换为 Func,否则仍然会有很多其他问题。再次感谢您指出出色的答案。
  • .Select(x => (Func<int,int>)(y => x + y)); 也应该可以工作..

标签: c# .net delegates lambda type-inference


【解决方案1】:

原因很简单:

编译如何得出它应该是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 之前。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多