2011-08-30 7 views
20

既にquestion on SO about "possible multiple enumerations"がありますが、この質問はより具体的です。"IsNullOrEmpty"チェックでも "IEnumerableの複数の列挙が可能"という警告が表示される

入力としてIEnumerable<string>を受け取り、その要素のそれぞれに対して所定の方法を実行する以下の方法を検討してください:IsNullOrEmpty

を実行するだけ拡張法である、上記のコードで

public static bool SomeMethod(IEnumerable<string> enumerable) 
{ 
    if (enumerable.IsNullOrEmpty()) 
    { 
     // throw exception. 
    } 
    else 
    { 
     return (enumerable.All(SomeBooleanMethod)); 
    } 
} 

return (!ReferenceEquals(enumerable, null) || enumerable.Any()); 

問題はReSharperが「可能な複数のIEnumerableの列挙」について警告していますが、実際に問題があるかどうかはわかりません。

私は警告の意味を理解していますが、無効または空の場合に例外をチェックしてスローする必要が本当にある場合は、この状況で本当に何ができますか?

+0

空のシーケンスが渡された場合、なぜこのメソッドをスローするのですか? 「この(空の)シーケンスのすべてのメンバーに何かする」という意味は完全に明白ですが、そうではありませんか?また、 '== null'ではなく' ReferenceEquals() 'を使う特別な理由はありますか? – AakashM

+0

これは実際にはありませんが、今はこれがコンストラクタであると想像してください。空のシーケンスからオブジェクトを構築できない場合、exceptioを投げてはいけませんか? – User

+1

確かに、もしあなたが何もできないのであれば、 *一般的に、私は、空の配列は空でない配列と同じように扱うべきだと言っています。 'List <>'は、例えば、空のシーケンスから構築することができます。もちろん私は一般的な話だけです。あなたはあなたの状況の詳細*を知っています。 – AakashM

答えて

30

これは、IEnumerableを複数回繰り返していることを意味します(最初にAny()を呼び出しています(少なくとも列挙型が要素を返すかどうかを確認するために反復を初期化する必要があります)。 All(最初から繰り返されます)。

ReSharperが警告している理由は、列挙可能な列挙は副作用を引き起こすことがあり、誤って2回反復すると副作用が2回発生する可能性があります。

+0

あなたは副作用を説明してください、または例が楽しいでしょうか。 –

+12

あなたの列挙型は、たとえば、ネットワークストリームからバイトを読み取ることができます(これは副作用を構成します)。一度列挙すると、すべてが問題なく、ストリームは一度に終了するまで読み込まれます。ただし、最初の繰り返しを中止してから、繰り返し実行すると、元のネットワークストリームが後方にシークできなくても、望ましくない動作が発生する可能性が高くなります。 – tdammers

+0

例をありがとうございました –

8

@tdammersは、AnyおよびAllで必要とされる2つの列挙型を示しています。空のシーケンスを拒否したいので、私が思いつくことができる最高のものは次のとおりです。

public static bool SomeMethod(IEnumerable<string> enumerable) 
{ 
    if (enumerable == null) 
     throw new ArgumentNullException(); 

    // Manually perform an All, keeping track of if there are any elements 
    bool anyElements = false; 

    bool result = true; 

    foreach (string item in enumerable) 
    { 
     anyElements = true; 
     result = result && SomeBooleanMethod(item); 

     // Can short-circuit here 
     if (!result) 
      break; 
    } 

    if (!anyElements) 
     throw new ArgumentException(); // Empty sequence is invalid argument 

    return result; 
} 
+1

努力のためにUpvoting。 –

関連する問題