【问题标题】:Wrong C# compiler error message on async lambda type inference关于异步 lambda 类型推断的错误 C# 编译器错误消息
【发布时间】:2012-11-10 00:06:59
【问题描述】:

我遇到了这个 C# 编译器错误,虽然我对编译器无法推断 lambda 的类型感到满意,但错误消息似乎是错误的。这是相关的代码:

Func<object> lambda = async () => { return await Task.FromResult(1); };

这是编译器错误:

错误 CS4010:无法将异步 lambda 表达式转换为委托类型“System.Func&lt;object&gt;”。异步 lambda 表达式可能返回 voidTaskTask&lt;T&gt;,它们都不能转换为 'System.Func&lt;object&gt;'。

我不太明白的部分是最后一句话。 lambda 确实返回了Task&lt;int&gt;,但是为什么编译器认为它应该尝试将其转换为System.Func&lt;object&gt;

另一方面,如果错误消息试图传达的是 System.Func&lt;Task&lt;int&gt;&gt; 不能分配给 System.Func&lt;object&gt;,由于通用委托协方差,这似乎不是这种情况,这意味着这只是好吧:

Func<object> lambda = new Func<Task<int>>(async () => { return await Task.FromResult(1); });

【问题讨论】:

  • 编译器应该将其转换为System.Func&lt;object&gt;,因为这是您声明变量的方式,并且它与异步委托不兼容。
  • async方法的返回类型必须是void,Task或者Task

标签: c# .net-4.5 async-await


【解决方案1】:

lambda 确实返回了Task&lt;int&gt;,但是为什么编译器认为它应该尝试将其转换为System.Func&lt;object&gt;

我认为错误信息措辞不当。它试图为 lambda 导出一个返回类型(可以是 voidTaskTask&lt;T&gt;),并将 lambda 转换为 Func&lt;object&gt;。我建议您在 Microsoft Connect 上提出问题,请求更清晰的错误消息。

另一方面,如果错误消息试图传达的是 System.Func&lt;Task&lt;int&gt;&gt; 不能分配给 System.Func&lt;object&gt;,由于通用委托协方差,情况似乎并非如此

是的,但编译器直到“晚于”大多数表达式才确定 lambda 表达式的类型。编译器看不到Func&lt;Task&lt;int&gt;&gt;(它只看到一个不带参数并返回TaskTask&lt;int&gt; 的lambda 表达式),因此它不会使用泛型委托变体。

我希望 Eric Lippert 发表一篇博文,介绍如何解析 async lambda 表达式,尤其是在方法重载选择的情况下。

【讨论】:

  • 感谢斯蒂芬,误导性错误消息正是我所关心的。只是想在报告之前得到一些快速反馈,我刚刚做了here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多