C# Linq源码解析之All

前言

在Dotnet开发过程中,All作为IEnumerable的扩展方法,十分常用。本文对Aggregate方法的关键源码进行简要分析,以方便大家日后更好的使用该方法。.

使用

确定序列中的所有元素是否都满足条件,如果都满足就返回true,如果有一个不满足就返回false

有这样一段代码,我们判断集合中的元素的性别是否都为男,我们就可以使用linq中的all方法

  public class UserInforMation
    {
        public string UserName { get; set; }
        public string Sex { get; set; }
      
    }
          List<UserInforMation> lstUserInforMations = new List<UserInforMation> {
            new UserInforMation{ UserName="张三",Sex="男"},
            new UserInforMation{ UserName="李四",Sex="男"},
            new UserInforMation{ UserName="王麻子",Sex="男"}
            };
    
            bool flag = lstUserInforMations.All(o => o.Sex == "男");

我们查看ALL的原型

public static bool All<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,bool> predicate);
原型参数
  • 第一个参数是我们source 元素的类型
  • 第二个参数是一个委托,该委托用于判断所有元素是否满足某个条件
Func<TSource,bool> predicate

这个func委托接收一个和源元素相同的参数类型,并返回一个bool!

返回

可以看出该方法返回的一个bool变量,如果每个元素都满足func,或者序列为空,则为 true;否则为 false!

 

这样我们把All的原型理解完了,就能够很轻易的写出All的源码!

我们使用foreach遍历源元素,如果有一个不满足我们就返回false,因为这个方法的定义是序列中的所有元素是否都满足条件才返回True,否则返回false!

  public static bool MyAll<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            if (source == null)
            {
                throw new Exception("source");
            }

            if (predicate == null)
            {
                throw new Exception("predicate");
            }

            foreach (TSource item in source)
            {
                if (!predicate(item))
                {
                    return false;
                }
            }

            return true;
        }

官方在这里埋了一个坑,官网对all有个说明,如果集合为空,这个方法也会返回true,所以我们在使用all的时候,一定要对集合判断是否含有元素,如果没有,就不要使用all了,这时候他返回的结果对于我们来说就是不对的了!看这样的一个例子

     List<UserInforMation> lstUserInforMations2 = new List<UserInforMation>();
            bool flag = lstUserInforMations.All(o => o.Sex == "男");

这时候就是返回true,所以我们在使用前最好进行判空

      List<UserInforMation> lstUserInforMations2 = new List<UserInforMation>();
            if (lstUserInforMations2.Any())
            {
                bool flag = lstUserInforMations.All(o => o.Sex == "男");
            }       

当然有的人觉得这是个bug,那么对于聪明的你们来说来改造这个源码不是手到擒来吗?今天我的介绍就到此结束了,既然看到了这里,还麻烦给个赞!明天给大家带来Any的源码解析!