null
最初のオプションは、チェックに合格したアイテムの結果として壊れることがあります。そのため、一致するアイテムがない場合でも、一致するアイテムはないと思われます。この特定の例には当てはまりませんが、一般的な場合には当てはまります。
ただし、ここでの2番目の例では、ソースシーケンスを2回(場合によっては)繰り返します。1回は結果があるかどうかを確認し、もう1回はその結果を取得します。ソースシーケンスがデータベースクエリを実行して、非常に高額になる可能性のある結果を取得する必要がある場合。このため、このオプションは、処理しているメモリ内コレクションがあり、それが特に大きくない(または必要な最初のアイテムがすぐに見つかる)ことが確実な場合にのみ使用する必要があります。
最初のオプションでこの特定のエッジケースについて心配する必要がある場合、または(必要なものの優れたセマンティック表現のために)Any
を使用する利点を取得したい場合は、次のパターンを使用できます。First
FirstOrDefault
var myVar = myCollection.Where(q => q.Id == 10)
.Take(1)
.ToList();
if (myVar.Any())
{
anotherVar = myVar.First().MyName;
}
必要に応じて、これを短縮する拡張メソッドを作成できます。
public static IEnumerable<T> FirstOrEmpty<T>(this IEnumerable<T> source)
{
//TODO: null check arguments
using (var iterator = source.GetEnumerator())
{
if (iterator.MoveNext())
return new T[] { iterator.Current };
else
return Enumerable.Empty<T>();
}
}
public static IEnumerable<T> FirstOrEmpty<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
return FirstOrEmpty(source.Where(predicate));
}
これにより、次のように書くことができます。
var myVar = myCollection.FirstOrEmpty(q => q.Id == 10);
if (myVar.Any())
{
anotherVar = myVar.First().MyName;
}