2

このC#コンパイラエラーに遭遇しました。コンパイラがラムダのタイプを推測できないことは問題ありませんが、エラーメッセージは間違っているようです。関連するコードは次のとおりです。

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

コンパイラエラーは次のとおりです。

エラーCS4010:非同期ラムダ式をデリゲート型' System.Func<object>'に変換できません。非同期ラムダ式はvoidTaskまたはを返す場合Task<T>がありますが、いずれも' System.Func<object>'に変換できません。

よくわからない部分が最後の文です。ラムダは確かに戻ってき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); });
4

1 に答える 1

2

ラムダは確かに戻ってきTask<int>ますが、なぜコンパイラはそれを変換しようとすべきだと考えるのSystem.Func<object>ですか?

エラーメッセージの表現が不十分だと思います。voidラムダのリターンタイプ( 、、、Taskまたは)を導出し、ラムダをにTask<T>変換しようとしています。より明確なエラーメッセージを要求するMicrosoftConnectで問題を提起することをお勧めします。Func<object>

一方、エラーメッセージが伝えようとしているのSystem.Func<Task<int>>がに割り当てることができないSystem.Func<object>場合は、ジェネリックデリゲートの共分散のおかげでそうではないようです。

本当ですが、コンパイラはほとんどの式より「遅く」なるまでラムダ式のタイプを決定しません。コンパイラーは認識しません(引数をとらずにまたはFunc<Task<int>>を返すラムダ式を認識します)。したがって、ジェネリックデリゲート分散を使用しません。TaskTask<int>

async特にメソッドのオーバーロード選択の場合に、EricLippertがラムダ式の解決方法に関するブログ投稿を行うことを期待しています。

于 2012-11-06T23:55:53.350 に答える