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

2020-08-31  本文已影响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}");
}
上一篇下一篇

猜你喜欢

热点阅读