如何FirstOrDefault扩展方法的作品? [英] How FirstOrDefault extension method works?

查看:160
本文介绍了如何FirstOrDefault扩展方法的作品?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道的扩展方法如何FirstOrDefault的作品?下列哪些算法之一它遵循?

I was wondering on how FirstOrDefault extension method works? Which one of the following algorithms does it follows?

使用:

var arr = new[] {1, 2, 3, 4, 5, 6, 7};
return arr.FirstOrDefault(x => x%2 == 0);

算法1:

for(int i = 0; i < arr.Length; i++)
{
   if(arr[i] % 2 == 0)
     return arr[i];
}
return 0;

算法2:

var list = new List<int>();
for(int i = 0; i < arr.Length; i++)
{
   if(arr[i] % 2 == 0)
     list.Add(arr[i]);
}
return list.Count == 0 ? 0 : list[0];

请问FirstOrDefault算法是足够聪明,选择最佳的一个或它严格遵循这些算法的任何一个?

Does the FirstOrDefault algorithm is smart enough to choose the optimal one or it strictly follow any one of these algorithms?

推荐答案

我看着反射

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    IList<TSource> list = source as IList<TSource>;
    if (list != null)
    {
        if (list.Count > 0)
        {
            return list[0];
        }
    }
    else
    {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                return enumerator.Current;
            }
        }
    }
    return default(TSource);
}

它试图用List做,如果集合可以被转换为IList的(并实现Count属性)。否则,它使用枚举。

It tries to do it with a List if the collection can be cast as IList (and implements the Count property). Otherwise it uses the Enumerator.

编辑:另一种方法是用predicate(我现在看到你所谈论的)是不是优化,依靠IEnumerable接口上执行的foreach而不是IList的

The other method with the predicate (which I now see you are talking about) is not as optimised and relies on the IEnumerable interface to perform a foreach rather than IList.

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource local in source)
    {
        if (predicate(local))
        {
            return local;
        }
    }
    return default(TSource);
}

这篇关于如何FirstOrDefault扩展方法的作品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆