第一个选项可能会由于null
通过检查的项目而被破坏,从而使您认为没有匹配的项目,即使它们是。它不适用于此特定示例,但可以适用于一般情况。
但是,这里的第二个示例(有时)迭代源序列两次,一次是查看是否有任何结果,然后再次获得该结果。如果源序列需要执行数据库查询以获取可能非常昂贵的结果。因此,如果您确定您正在处理一个内存中的集合并且它不是特别大(或者您需要的第一个项目将很快找到),您应该只使用此选项。
如果您需要担心第一个选项的这种特殊边缘情况,或者您想获得使用的好处,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;
}