2012-11-06 78 views
2

我碰到了這個C#編譯器錯誤,雖然我確定編譯器不能推斷lambda的類型,但錯誤消息看起來不對。下面是相關的代碼:異步lambda類型推斷錯誤的C#編譯器錯誤信息

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

和這裏的編譯器錯誤:

error CS4010: Cannot convert async lambda expression to delegate type ' System.Func<object> '. An async lambda expression may return void , Task or Task<T> , none of which are convertible to ' 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); }); 
+0

編譯器應該將它轉換爲'System.Func ',因爲這是你聲明變量的方式,它與異步代理不兼容。 –

+1

*異步方法的返回類型必須爲空,任務或任務 * –

回答

2

The lambda is indeed returning Task<int> , but why does the compiler think that it should try to convert it to System.Func<object> ?

我認爲錯誤消息的措辭不當。它試圖爲lambda導出返回類型(可以是void,TaskTask<T>),並將轉換爲lambdaFunc<object>。我建議您在Microsoft Connect上提出一個問題,要求提供更清晰的錯誤消息。

On the other hand, if what the error message is trying to convey is that System.Func<Task<int>> cannot be assigned to System.Func<object> , that doesn't seem to be the case thanks to generic delegate covariance

確實如此,但編譯器不會確定lambda表達式的類型,直到「晚於」才比大多數表達式爲止。編譯器沒有看到Func<Task<int>>(它只是看到一個不帶參數的lambda表達式,並返回TaskTask<int>),所以它不會使用泛型委託方差。

我希望Eric Lippert會寫一篇關於async lambda表達式如何解決的博客文章,特別是在方法過載選擇的情況下。

+0

謝謝斯蒂芬,誤導性的錯誤信息正是我所關心的。只是想在報告之前獲得一些快速反饋,我剛剛在[這裏](https://connect.microsoft.com/VisualStudio/feedback/details/770315/wrong-c-compiler-error-message-on-async -Lambda型推理)。 – Simone