如何在LINQ中评估SingleOrDefault()方法?它是否在幕后使用二进制搜索?
答案 0 :(得分:12)
比试图用文字解释更好,我想我只是在.NET Framework中发布确切的实现代码,使用Reflector程序检索(并且稍微重新格式化)。
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw Error.ArgumentNull("source");
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
switch (list.Count)
{
case 0:
return default(TSource);
case 1:
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
return default(TSource);
TSource current = enumerator.Current;
if (!enumerator.MoveNext())
return current;
}
}
throw Error.MoreThanOneElement();
}
如果对象属于IList<T>
类型,那么观察到优化是非常有趣的,这似乎是非常明智的。它简单地回过头来枚举对象,否则如果对象没有比IEnumerable<T>
更具体的特性,那么这就是你期望的那样。
请注意,它不能使用二进制搜索,因为该对象不一定代表已排序的集合。 (事实上,在几乎所有的使用案例中,它都不会。)
答案 1 :(得分:2)
我认为它只是执行查询,如果结果计数为零,则返回该类的默认实例。如果结果计数为1,则返回该实例,如果结果计数大于1,则抛出异常。
答案 2 :(得分:0)
我不认为它会进行任何搜索,而是关于获取源[list,result set等]的第一个元素。
我最好的猜测是它只是拉出了第一个元素。如果没有,则返回默认值(null,0,false等)。如果有第一个,它会尝试拉出第二个结果。如果有第二个结果则抛出异常。否则返回第一个结果。