2016-12-15 7 views
3

私は方法があります:到達できないコードを追加せずにこの非同期ラムダをコンパイルするにはどうすればよいですか?

void MyMethod<T>(params Func<T>[] funcs) { } 

私は非同期ラムダでそれを呼び出すようにしたい:

MyMethod(async() => 1, async() => 2, async() => 3); 

それは働きます!しかし、3番目のラムダが例外をスローするようにしたいのですが?上記

MyMethod(async() => 1, async() => 2, async() => { throw new Exception(); }); 

コンパイルされませんが、それは、2つの同一のエラー得られます。

CS0201のみ代入、インクリメント、デクリメント、呼び出し、新しいオブジェクト式がステートメントとして使用することができますが

なぜこのエラーが出るのか分かりませんが、コンパイルできない理由を理解しています。最初の2つのラムダはFunc<Task<int>>ですが、最後はFunc<Task>です。私はそれが私により良いコンパイルエラーを与えると期待していますが、この問題を脇に置いてみましょう。

コンパイルするにはどうすればよいですか?私はおそらく、3番目の非同期ラムダのために生成したいタスクのタイプをコンパイラに伝えなければならないでしょう。私が見つけた一つの方法は、throw文の後return文を指定するには、次のとおりです。

MyMethod(async() => 1, async() => 2, async() => { throw new Exception(); return 3; }); 

別に醜いと紛らわしいことから、それはコンパイラ警告を生成:

CS0162到達不能コードが

を検出しました

コンパイラを幸せにする方法を教えてください。到達不能なコードをコンパイルするのを避けるにはどうすればよいですか?非同期ラムダによって返されるタスクの種類を指定する別の方法はありますか?

また、上記の例でCS0201エラーが発生するのはなぜですか?

+2

なぜあなたは 'await'を使用していないことを考えると、最初の場所で非同期ラムダを使用していますか? – Servy

+0

@Servy:実際のコードは待っています。例外をスローする3番目のラムダでさえ待っています。これは、コードを削除したものです。 –

+0

実際のコードを実際に表す例を示します。 – Servy

答えて

6

問題は、コンパイラは最後のラムダは何の戻り値の型を持っていないので、TaskであるためにあなたのTを推測することです。

したがって、最初のラムダを戻り値なしとして解析しようとします。つまり、式ではなく文として有効でなければなりません。 1はステートメントとしては無効なので、この奇妙なサウンドエラーです。 、あなたのコードのコンパイルを行い、明示的にジェネリック型パラメータを渡すために

MyMethod<Task<int>>(async() => 1, async() => 2, async() => { throw new Exception(); }); 

example

+0

実際のコードがlambdasで待っているのと同じように 'async'を削除できません。例外をスローする3番目のラムダでさえ待っています。これは、コードを削除したものです。 –

+0

例をそのまま使用しても、 'async'を削除するとセマンティクスが変更されます。 – Servy

+0

@AllonGuralnek:編集済みの回答を参照してください。 – SLaks

2

あなたの最初の例では、ラムダは、コンテキストなし(Func<Task<int>>ではありません、それはActionだろう)、それはそのデリゲートのための有効なラムダです。それはちょうどそれにキャスト、あなたがしたいデリゲートに有効ですので:

MyMethod(async() => 1, 
    async() => 2, 
    (Func<Task<int>>)(async() => { throw new Exception(); })); 
+0

あまりありません。それが問題だった場合、無効な変換エラーが発生します。実際の問題は、その推論のために他のラムダにある。 – SLaks

+0

これもうまくいくようです。ありがとう! –

関連する問題