LINQ如何实现SingleOrDefault()方法?

时间:2009-05-27 12:10:11

标签: linq

如何在LINQ中评估SingleOrDefault()方法?它是否在幕后使用二进制搜索?

3 个答案:

答案 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等)。如果有第一个,它会尝试拉出第二个结果。如果有第二个结果则抛出异常。否则返回第一个结果。