タイプIEnumerable
のT
を返す次のメソッドがあります。 yield return
から遅延読み込みIEnumerable
を除いて、メソッドの実装は重要ではありません。結果として何百万ものアイテムが含まれる可能性があるため、これが必要です。
public IEnumerable<T> Parse()
{
foreach(...)
{
yield return parsedObject;
}
}
問題:
IEnumerable
にアイテムがあるかどうかを判断するために使用できる次のプロパティがあります。
public bool HasItems
{
get
{
return Parse().Take(1).SingleOrDefault() != null;
}
}
これを行うためのより良い方法はおそらくありますか?
IEnumerable.Any()
は、シーケンスに要素がある場合はtrue
を返し、シーケンスに要素がない場合はfalse
を返します。このメソッドは、最初の要素を通過した場合はtrueを返し、通過しなかった場合はfalseを返すため、シーケンス全体(最大1つの要素のみ)を反復しません。
ハウツー:反復せずにIEnumerable <T>からアイテムをカウントしますか?Enumerable
はlazy、先読みの「リスト」、そして量子力学のように、それを調査する行為はその状態を変えます。
確認を参照してください: https://dotnetfiddle.net/GPMVXH
_ var sideeffect = 0;
var enumerable = Enumerable.Range(1, 10).Select(i => {
// show how many times it happens
sideeffect++;
return i;
});
// will 'enumerate' one item!
if(enumerable.Any()) Console.WriteLine("There are items in the list; sideeffect={0}", sideeffect);
_
enumerable.Any()
は、リストに項目があるかどうかを確認する最もクリーンな方法です。 if(null != (list = enumerable as ICollection<T>) && list.Any()) return true
のような怠惰ではないものにキャストしてみることができます。
または、シナリオでEnumerator
を使用し、列挙する前に予備チェックを行うことが許可されている場合があります。
_var e = enumerable.GetEnumerator();
// check first
if(!e.MoveNext()) return;
// do some stuff, then enumerate the list
do {
actOn(e.Current); // do stuff with the current item
} while(e.MoveNext()); // stop when we don't have anything else
_