【C#】小知识 #6 : Lambda + LINQ 使用statement body(语句块)不使用expressio

最近看到一个使用Lambda + LINQ不好的例子,举例:

资讯公司员工辛苦上市,尾牙特别奖赏员工

每人最起码发放10000奖金假如入职满一年奖金 +20000,满两年奖金 +40000因为资讯部门KPI特别好,增加额外奖金 +30000

以下是模拟他的写法,可以看到缺点

重複呼叫方法 GetYearDif每个条件写一个三元运算式,条件变多会难以维护
void Main(){    //测试资料,实际上资料在Excelvar datas = new List<Employee>(){new Employee{Name="小明",Department=Dep.资讯部,EntryDate=DateTime.Parse("2015/01/01")},new Employee{Name="小华",Department=Dep.资讯部,EntryDate=DateTime.Parse("2017/01/01")},new Employee{Name="小新",Department=Dep.业务部,EntryDate=DateTime.Parse("2014/01/01")}};NewYearBonusService.Excute(datas);}abstract class NewYearBonusService{private const decimal DefaultBonus = 10000;public static void Excute(IEnumerable<Employee> datas){datas.Select(s => new {Employee = s,bonus=s.Department == Dep.资讯部 && GetYearDif(DateTime.Now, s.EntryDate) >= 2 ? DefaultBonus + 30000 + 40000 :s.Department == Dep.资讯部 && GetYearDif(DateTime.Now, s.EntryDate) >= 1 ? DefaultBonus + 30000 + 20000:s.Department == Dep.资讯部 ? DefaultBonus + 30000:DefaultBonus}).Dump();}private static int GetYearDif(DateTime d1, DateTime d2){var dif = (int)((d2 - d1).TotalDays / 365);if (dif < 0) dif *= -1;return dif;}}enum Dep{ 资讯部,业务部 }class Employee{public string Name { get; set; }public Dep Department { get; set; }public DateTime EntryDate  { get; set; }}

询问对方才发现他以为只能使用expression body,不知道可以使用statement body,在这个例子其实可以改成语句块作法,如以下範例:
1.可以加上if判断
2.宣告变数重複利用
3.甚至可以做简单防呆

abstract class NewYearBonusService{private const decimal DefaultBonus = 10000;public static void Excute(IEnumerable<Employee> datas){datas.Select(s =>{var bonus = DefaultBonus;var yearDif = GetYearDif(DateTime.Now,s.EntryDate);if (s == null) throw new Exception("资料为空,请检查资料");if (s.Department == Dep.资讯部 ) bonus+=30000;if (yearDif>=2) bonus+=40000; else if (yearDif>=1) bonus+= 20000;return new { Employee=s ,bonus};}).Dump();}}

2018-12-26.21.22.23-image.png

为什么可以这么方便?可以藉由反编译程式码看到底层还是委託(delegate),只是系统帮我们生成而已。
2018-12-26.11.25.19-image.png

补充

这是LINQ + Lambda才能使用的方法,单纯LINQ是不能简单套用
2018-12-26.11.37.20-image.png使用编辑器是LINQPAD,Dump()是里面的扩充方法,可以用Console.WriteLine取代

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章