2017-02-14 8 views
2

は、なぜこのコードん:IEnumeratorが到達不能であっても、少なくとも1つのyieldステートメントを持つ必要があるのはなぜですか?

public IEnumerator Test() 
{ 
} 

はあなたにエラーを与える:

Error CS0161 'Test.GetEnumerator()': not all code paths return a value

しかし、このコード:

public IEnumerator Test() 
{ 
    if(false) 
     yield return 0; 
} 

はないのですか? (最初のMoveNext()はfalseを返します)

コルーチンとしてIEnumeratorを使用する場合、コルーチン(IEnumerator)を非同期操作をまだしていない(何も生成していませんが)将来それをする。 C#の仕様から

+1

ダミーのif文の代わりに 'yield break;'を使うこともできます。 –

答えて

3

A block that contains one or more yield statements (§8.14) is called an iterator block. Iterator blocks are used to implement function members as iterators (§10.14).

あなたが一つ以上の収量文を持っているのであれば、関係なく、到達可能かどうか、あなたの方法は、(イテレータ・クラスを生成しますボンネットの下)イテレータではありません。しかし、yieldステートメントがない場合は、戻り値がIEnumerableの序数メソッド(イテレータではありません)です。何らかの値を返す他の方法として、必要な型の値を返すか、メソッド本体から例外をスローする必要があります。 stringまたはintの値を返すメソッドがある場合、同じ規則が適用されます。

0

任意のyield文は全くメソッドブロック内に存在していない場合は、その後、それは反復子ブロックないと、コンパイラは、あなたがそれに関連した変換を実行したいない考えを持っていません。それはあなたが価値を返す他の方法と同じように扱います。

コンパイラチームは、彼らがasyncを行なったし、存在する場合、メソッド反復子ブロック製の、方法、の署名に新しいキーワードを追加して何を行っている可能性があり、体内のyield文を許可し、希望空の身体を何も得られないものとして扱うことができるが、彼らはしないことを選んだ。

メソッド本体にyieldステートメントがある場合、メソッドが適切にコンパイルされて実行されるために実際に確実にヒットする必要はありません。メソッドの最後に当たる反復子ブロックでは、まだ商品が生成されていなくてもシーケンスが終了したことを意味します。これは完全に分かりやすい動作です。このメソッドには、返す値がIEnumerableまたはIEnumeratorのまま残っていますが、値は出力されません。

関連する問題