2

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

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

这是编译器错误:

错误 CS4010:无法将异步 lambda 表达式转换为委托类型“ System.Func<object>”。异步 lambda 表达式可能返回或void,它们都不能转换为 ' '。TaskTask<T>System.Func<object>

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

另一方面,如果错误消息试图传达的是 that System.Func<Task<int>>cannot be assigned to System.Func<object>,那么由于通用委托协方差,这似乎不是这种情况,这意味着它可以正常工作:

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

1 回答 1

2

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

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

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

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

我希望 Eric Lippert 会写一篇关于如何async解析 lambda 表达式的博文,特别是在方法重载选择的情况下。

于 2012-11-06T23:55:53.350 回答