美文网首页
C#从使用“lambda”、“linq”到引入封装思想

C#从使用“lambda”、“linq”到引入封装思想

作者: 浅谈码生活 | 来源:发表于2020-08-31 11:19 被阅读0次

    Lambda的前世今生
    Lambda的本质是一个方法,多播委托中是不能把Lambda表达式-=,因为Lambda表达式其实是一个方法,不同的lambda表达式就是不同的方法。
    .Netframework1.0/1.1时代

    NoReturnNoPara method = new NoReturnNoPara(DoNothing);
    method .Invoke();
    

    .NetFramework2.0时代,匿名方法增加了一个delegate关键字,可以访问到参数以外的局部变量

    NoReturnWithPara method = new NoReturnWithPara(delegate (int id, string name)
    {
          Console.WriteLine($"{id} {name}...");
          Console.WriteLine(i);
    });
    method.Invoke(123, "Test");
    

    .NetFramework3.0时代,去掉delegate关键字,添加一个=> "goes to"

    NoReturnWithPara method = new NoReturnWithPara ((int id,string name)=>
    {
          Console.WriteLine($"{id} {name}...");
          Console.WriteLine(i);
    });
    method.Invoke(123, "Test");
    

    .NetFramework3.0 后期,去掉了匿名方法的参数类型

    NoReturnWithPara method = new NoReturnWithPara((id,name)=>
    {
          Console.WriteLine($"{id} {name}...");
          Console.WriteLine(i);
    });
    method.Invoke(123, "Test");
    

    ** Linq使用**
    相信在日常的开发中,大家在对集合进行处理事都使用过Linq,但不知道大家有没有究其Linq的本质呢?
    下面我将使用代码的方式将"List.Where()"进行拆解开:

    public static class MethodExtension
    {
          public static IEnumerable<T> CustomWhere<T>(this IEnumerable<T> resource, Func<T, bool> func) where T : class
          {
                    List<T> list = new List<T>();
                    foreach (var item in resource)
                    {
                           if (func.Invoke(item))
                          {
                               list.Add(item);
                           }
                    }
                    return list;
          }
    }
    public class App
    {
          public static void Main(string[] args)
         { 
                 //初始化集合
                 List<string> strList = new List<string>();
                 //定义函数体
                 Func<string,bool> func = (s=>{return s.Length > 10};);
                //使用上述的扩展方法
                 strList.CustomWhere(func);
                //进一步演化得到
                 strList.CustomWhere(s =>s.Lenght >10);
         }
    }
    

    由上面的拆解发现,其实Linq就是将我们可变的逻辑进行封装成委托来当作参数进行传递,而不变的逻辑封装成方法体来接收可变的逻辑参数,而这种思想也就是早期微软特别推崇的“封装思想”。
    了解了“Linq”的基本原理后,那就在来看一下Linq中的其他封装方法:

    //Select--投影
    var list = studentList.Where<Student>(s => s.Age < 30)
                     .Select(s => new
                      {
                            IdName = s.Id + s.Name,
                            ClassName = s.ClassId == 2 ? "2班" : "其他班"
                       });
     foreach (var item in list)
     {
            Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName); 
     }
    //OrderBy,OrderByDescending,Skip,Take
     var list = studentList.Where<Student>(s => s.Age < 30)//条件过滤
                                         .Select(s => new//投影
                                         {
                                             Id = s.Id,
                                             ClassId = s.ClassId,
                                             IdName = s.Id + s.Name,
                                             ClassName = s.ClassId == 2 ? "2班" : "其他班"
                                         })
                                         .OrderBy(s => s.Id)//排序
                                         .OrderByDescending(s => s.ClassId)//倒排
                                         .Skip(2)//跳过几条
                                         .Take(3)//获取几条
                                         ;
    foreach (var item in list)
    {
          Console.WriteLine($"Name={item.ClassName}  Age={item.IdName}");
    }
    //GroupBy
    var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
    {
          key = sg.Key,
          maxAge = sg.Max(t => t.Age)
    });
    foreach (var item in list)
    {
          Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
    }
    //Join
    var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
    {
         Name = s.Name,
         CalssName = c.ClassName
    });
    foreach (var item in list)
    {
          Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
    //left Join
    var list = from s in studentList
                               join c in classList on s.ClassId equals c.Id
                               into scList
                               from sc in scList.DefaultIfEmpty()//
                               select new
                               {
                                   Name = s.Name,
                                   CalssName = sc == null ? "无班级" : sc.ClassName//c变sc,为空则用
                               };
    foreach (var item in list)
    {
            Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
    

    相关文章

      网友评论

          本文标题:C#从使用“lambda”、“linq”到引入封装思想

          本文链接:https://www.haomeiwen.com/subject/omqusktx.html