9

IEnumerable かどうかを判断するために、最も再利用可能でありながらエレガントなコードを見つけようとしています。理想的には、これは、IEnumerable が空かどうかを確認する必要があるときにいつでも呼び出すことができる関数であるべきです。

IEnumerable は技術的にコレクション (またはイテレータのキュー) をカプセル化して、基礎となる結果をそれが繰り返されるため、問題が発生します。ただし、これは IEnumerable.Count() の実装の障害にもなり、MS がそれを提供するのを止めることはありませんでした。

だから私は、誰かがより良いものを持っているかどうかを確認するためにそれをSOに入れ、他の誰かがそれを役に立つと思うべきだと思った.

編集: うわー、IEnumerable.Any について知らなかったなんて信じられない。私はそれが存在することを知っていましたが、それが何をするかをわざわざチェックすることはありませんでした. これを教訓にしましょう。ドキュメントを読んでください。メソッド名があなたが望むことをすることを意味しないからといって、それがあなたが望むことをしないという意味ではありません.

4

5 に答える 5

22
!enumerable.Any()

最初の要素のみを取得しようとします。

これがどのように/なぜ機能するかを拡張するために、 any はIEnumerable、指定された関数のコンポーネントのいずれかが一致するかどうかを判断します。何も指定されていない場合、すべてのコンポーネントが成功します。つまり、列挙可能な要素に要素が存在する場合、関数は true を返します。

于 2008-09-22T20:22:44.797 に答える
2

.net 1/2 の場合:

IEnumerator e;
try
{
   e = enumerable.GetEnumerator();
   return e.MoveNext();
}
finally
{ 
    if (e is IDisposable)
        e.Dispose();
}

または、ジェネリックを使用する場合:

using (IEnumerator<T> e = enumerable.GetEnumerator())
{
    return e.MoveNext();
}
于 2008-09-22T20:39:16.177 に答える
2

確かに完璧な答えはありません。IEnumerable は反復のみをサポートし、列挙が反復可能であることを保証しません。MoveNext を少なくとも 1 回呼び出さない限り、列挙に要素が含まれているかどうかを確認することはできません。一度実行すると、列挙を再利用できることを保証できません。IEnumerable.Reset が NotSupportedException をスローすることは許容されます。http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspxから:

「Reset メソッドは、COM の相互運用性のために提供されています。必ずしも実装する必要はありません。代わりに、実装者は単に NotSupportedException をスローできます。」

IEnumerable<T>.Count や IEnumerable<T>.Any などの拡張メソッドは、内部で MoveNext を呼び出す必要があります。便利なラッパーですが、列挙がリセットをサポートしていない(まれな)ケースでは、問題が発生する可能性があるという事実を避けてはなりません。

于 2008-09-22T20:51:21.887 に答える
0

これらのメソッドのいずれかで注意すべきことの 1 つは、すべての列挙をロールバックできるわけではないことです。たとえば、System.Data.IDataReader のすべての実装は 1 回しか実行できません。

このような場合、foreach一度もループしない可能性があるという事実を考慮している限り、実際にはループにコストはかかりません。

于 2008-09-22T20:43:48.723 に答える
0

最初のメソッドには、空の拡張メソッドの単純な実装があります: http://signum.codeplex.com/SourceControl/changeset/view/25903#510468

于 2009-03-13T02:16:28.340 に答える