zoukankan      html  css  js  c++  java
  • Linq特取操作之ElementAt,Single,Last,First源码分析

    Linq特取操作之ElementAt,Single,Last,First源码分析

    一:linq的特取操作

    First/FirstOrDefault, Last/LastOrDefault, ElementAt/ElementAtOrDefault, Single/SingleOrDefault


    二:First/FirstOrDefault 介绍

    解释: 用于返回序列中的第一个值


    异常: 如果当前集合没有值的话,如果你取第一个值,会抛出throw Error.NoElements();异常。

    public static TSource First<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;
    }
    }
    }
    throw Error.NoElements();
    }

    ===> FirstOrDefault <=====

    if(list.count==0) return default(TSource)


    三:Last/LastOrDefault

    默认直接返回序列的最后一个元素。

    我们也可以使用Func条件,返回满足指定条件的最后一个元素。

    static void Main(string[] args)
    {
    var nums = new int[] { 4, 3, 2 };

    var query = nums.LastOrDefault(i => i % 2 == 0);
    }

    源码:

    => throw Error.NoElements();

    => return default(TSource);


    四: ElementAt/ElementAtOrDefault

    ElementAtOrDefault: 这个方便就避免了我们在代码写过多的if判断。【判断是否超出索引】

    如果现在用此方法,你就不需要担心这个问题了。。。


    源码分析:【效率分析】

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


    可以看到,FCL中已经给我们做了一个“索引判断”,所以我们就不需要再代码中进行判断了,这样就方便我们更加的
    关于业务逻辑。


    五:Single/SingleOrDefault

    解释:返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常。【三个结果】

    First:第一个元素

    Single:唯一元素


    class Program
    {
    static void Main(string[] args)
    {
    var nums = new int[] { 4, 3, 1, 2 };

    var query = nums.FirstOrDefault(i => i % 2 == 0); //nums[2];

    var query2 = nums.SingleOrDefault(i => i % 2 == 0);
    }
    }


    我们再看源码解释:

    public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
    if (source == null)
    {
    throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
    throw Error.ArgumentNull("predicate");
    }
    TSource result = default(TSource);
    long num = 0L;
    checked
    {
    foreach (TSource current in source)
    {
    if (predicate(current))
    {
    result = current;
    num += 1L;
    }
    }
    if (num == 0L)
    {
    return default(TSource);
    }
    if (num != 1L)
    {
    throw Error.MoreThanOneMatch();
    }
    return result;
    }
    }

  • 相关阅读:
    《淘宝网》之系统质量属性分析
    《架构漫谈》读后感 之“关于软件架构师如何工作”
    《软件需求》读后感06
    《软件需求》读后感05
    Cforeach的详细用法--【转】
    事件(Event)(onclick,onchange,onload,onunload,onfocus,onblur,onselect,onmuse)【转载】
    十七、Mysql的主从(一)--主从原理
    十七、Mysql的主从(二)--主从复制部署
    十六、mysql的备份与恢复(三)--xtrabackup(XBK、Xbackup)
    十六、mysql的备份与恢复(二)--mysqldump
  • 原文地址:https://www.cnblogs.com/dragon-L/p/6487096.html
Copyright © 2011-2022 走看看