异步lambda类型推断错误的C#编译器错误消息

时间:2012-11-06 22:03:41

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

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

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

这是编译器错误:

  

错误CS4010:无法将异步lambda表达式转换为委托类型“System.Func<object>”。异步lambda表达式可能会返回voidTaskTask<T>,其中任何一个都无法转换为“System.Func<object>”。

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

另一方面,如果错误消息试图传达的是System.Func<Task<int>>无法分配给System.Func<object>,那么由于通用代表协方差意味着这种情况似乎并非如此这样可以正常工作:

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

1 个答案:

答案 0 :(得分:2)

  

lambda确实正在返回Task<int>,但为什么编译器会认为它应该尝试将其转换为System.Func<object>

我认为错误信息措辞不佳。它试图导出lambda的返回类型(可以是voidTaskTask<T>),并将 lambda 转换为{{1} }。我建议您在Microsoft Connect上引发一个问题,要求提供更清晰的错误消息。

  

另一方面,如果错误消息试图传达的是Func<object>无法分配给System.Func<Task<int>>,那么由于通用委托协方差,情况似乎并非如此

是的,但编译器直到“晚于”大多数表达式才确定lambda表达式的类型。编译器没有看到System.Func<object>(它只看到一个不带参数的lambda表达式并返回Func<Task<int>>Task),因此它不会使用泛型委托方差。

我希望Eric Lippert能够发表关于如何解析Task<int> lambda表达式的博客文章,特别是在方法过载选择的情况下。