2009-07-19 13 views
4

いくつかのパラメータをチェックする必要があり、検証された場合にIEnumerableを返すメソッドを記述しています。例えば。名前付きイテレータと例外

public static IEnumerable<double> GetEnum(int param) 
{ 
    if (!IsValidParameter(param)) 
    { 
     throw new Exception(); 
    } 

    while(true) 
    { 
     yield return 5.0; 
    } 
} 

は、しかし、私が悪いのパラメータを持つ私のユニットテストを実行したとき、私は、理由は遅延評価の信じているが、まだIEnumerableをのいずれかの方法を呼び出すことはありませんが、例外がスローされていません。

[Test] 
[ExpectedException(typeof(Exception))] 
void Test() 
{ 
    var ie = GetEnum(bad_param); 
} 

私はGetEnumのパラメータをチェックし、Fooのを呼び出し、その後、(Fooのことを言う)別の関数でのIEnumerableを構築することにより、物事を修正することができますが、複数の関数を作成することなく、解決策はありますか?

乾杯、ユルゲン

答えて

9

により反復子ブロックが定義されている方法に、あなたは現在、これを実現するために二つの方法が必要になります。

public static IEnumerable<double> GetEnum(int param) { 
    if (!IsValidParameter(param)) { 
     throw new Exception(); 
    } 
    return GetEnumCore(param); 
} 
private static IEnumerable<double> GetEnumCore(int param) { 
    while(true) { 
     yield return 5.0; 
    } 
} 

だけ反復子ブロック(GetEnumCore)が延期されました。 GetEnumがすぐに実行され、チェックが実行されます。

+0

コンパイラが両方のメソッドを1つのイテレータブロックに減らすのに十分にスマートであるかどうかは、実際には分かりました。先端のおかげで、マーク。 –

2

あなたは多分ちょうど根本列挙子を使用して反復を開始してもらえますか?

[Test] 
[ExpectedException(typeof(Exception))] 
void Test() 
{ 
    var ie = GetEnum(bad_param); 
    var en = ie.GetEnumerator(); 
    en.MoveNext(); 
} 
+0

私は列挙子のこの怠惰な動作を理解していますが、以前に例外をスローする方法はありませんか?名前付き反復のために生成されたクラスのコンストラクタで言うことができますか? – Jurgen

2

開始しない限り、メソッドを列挙することはありません。あなた、あなたのテストに列挙してみてください:

var ie = GetEnum(bad_param).First(); 
関連する問題