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}");
}