一起谈.NET技术,【More Effective C#】Lambda表达式优化

  使用Lambda表达式将会造成Lambda表达式主题部分的代码重复.


1. var allEmployees = new List<Employee>() {
2. new Employee {
3. EmployeeId = 1, Classification = 1, FirstName = "Skin", LastName = "Sen" } };
4. var earlyFolks = from e in allEmployees
5. where e.MonthlySalary < 4000 && e.Classification == 1 && e.YearsOfService > 20
6. select e;

  若每当我们要获取一次不同工薪阶层的数据.就要重复一次.相信久经"高重用,松耦合"定律的你.肯定会想尽办法将其实现高重用,松耦合.在以前方法调用的时代.可能你会将其提炼出


1. private static bool LowPaidSalaried(Employee e, int salar)
2. {
3. return e.MonthlySalary < salar && e.Classification == 1;
4. }

  这样,每次我们调用的时候,将大大减少代码量,提高可复用性


var earlyFolks = from e in allEmployee
where LowPaidSalaried(e, 4000) && e.YearsOfService > 20
select e;

  然而,很不幸的是.在这里.这种重构的方式反倒降低了其可重用性.实际上,第一种方法的可重用性比第二种方法更高些.为什么呢?明明已经提炼出重用方法了.这与Lambda表达式的求值,解析以及最终的执行方式有关.

  前面的<<LINQ表达式与方法调用的映射>>里说过.编译器会根据不同的LINQ Provider将Lambda表达式转换成不同的内容来执行.对于LINQ to Object.将转换成委托方法.而LINQ to SQL则是转换成表达式数.在数据迭代时才会转换成SQL语句执行.所以.若我们是在LINQ2SQL或ADO.Net EF中如此重构.编译期通过了.但运行时将出错.因为无法将你的自定义方法转换成相关的SQL语句.,因此.将抛出一个异常.

  难道,Lambda表达式就只能重复再重复了吗?当然不是.在这里.延迟执行很好的将其作用发挥得淋漓精致.前面说过.延迟执行保存的并不是值,而是获取值的方法或者步骤.这样,每次我们调用完"获取"数据的方法.实际上.数据还没获得.得到的.只是一系列的"步骤".我们可以在步骤的的基础上再添加步骤.这样.就完美的实现了Lambda下的重构.


1. public static IQueryable<Employee>
     LowPaidSalaried(this IQueryable<Employee> sequence)
2. {
3. return from s in sequence
4. where s.Classification == 1 && s.MonthlySalary < 4000
5. select s;
6. }var allEmployees = FindAllEmployees();
7. var salaried = allEmployees.LowPaidSalaried();

  这样.只有在需要数据的时候,才会根据"步骤"得到相应的数据.对于IEnumerable<T>,我们可以使用yield return来返回序列.

  在复杂的查询中服用Lambda表达式最有效的办法就是封装封闭泛型类型的查询创建扩展方法.通过包含Lambda表达式的小方法叠加"步骤".从而达到最有效的优化.

时间: 2024-08-02 16:54:09

一起谈.NET技术,【More Effective C#】Lambda表达式优化的相关文章

《圣殿祭司的ASP.NET4.0专家技术手册》----2-11 Lambda表达式

2-11 Lambda表达式 圣殿祭司的ASP.NET4.0专家技术手册 Lambda表达式(Lambda Expressions)其功能属于Anonymous Function,但比.NET 2.0的匿名方法具备更强能力,语法更为简洁,应用的场景更为广泛. Lambda表达式主要是使用"=>"符号表示其表达式,=>符号在英文字义表示"goes to". 范例2-10 Lambda 表达式在Delegate委托上的应用 Lambda表达式可以建立Dele

浅谈Java 7的闭包与Lambda表达式之优劣

前几天Oracle推出了Java 7官方的闭包与Lambda表达式的第一个实现,这基本上也是最终在正式版中 的样式了.看了这个实现之后,我的第一感觉便是"丑",当然不排除这是因为看惯了其他语言中实现的 缘故.后来再仔细看了看又想了想,发现Java 7的实现也并非毫无可取之处,但似乎又感到某些做法上有 一些问题.总之整个过程颇为有趣,决定将我的想法记录下来,希望可以吸引人来一起讨论一下. Java 7中的Lambda表达式 Java 7中的Lambda表达式有两种形式,首先是第一种: #

【More Effective C#】Lambda表达式优化

使用Lambda表达式将会造成Lambda表达式主题部分的代码重复. 1. var allEmployees = new List<Employee>() { 2. new Employee { 3. EmployeeId = 1, Classification = 1, FirstName = "Skin", LastName = "Sen" } }; 4. var earlyFolks = from e in allEmployees 5. wher

一起谈.NET技术,Silverlight程序集缓存巧妙设置 优化用户体验

Silverlight中的程序集缓存可以将一些独立的程序集放在XAP包外边并可以缓存在客户端的浏览器中,这样就可以减少程序启动时下载XAP包的时间.默认情况下Silverlight并没有开启程序集缓存,因此需要自己动手开启. 右键打开项目的属性,并在通过使用应用程库缓存较小XAP大小选项打钩,如图: 在没选择此项之前编译项目看一下XAP中的DLL,如图: 重新编译项目,选择显示所有文件然后打开Bin\Debug目录,会看到每一个缓存程序集都有自己的zip文件包.比如,如果使用了System.Wi

一起谈.NET技术,Silverlight发布时的优化工作(上)

最近做开发时,silverlight的xap越来越大,如果不进行优化严重影响到客户端的体验,因此看了一些资料,总结一下. 一.XAP包是可分解的 Silverlight应用最终是借助于http协议以web形式到达客户端的,我们编写的silverlight包,就是xap,其实是一个压缩包,包含了许多个控件及资源,可以通过更改后缀为ZIP,通过右键打开一探究竟. 更改后缀后再使用压缩软件打开后发现. 了解这个基本知识后呢,就可以从分解这个xap包开始了进行优化工作了,这里的优化工作分为两部分: si

一起谈.NET技术,Silverlight发布时的优化工作(下)

相关文章:Silverlight发布时的优化工作(上) 一. 项目资源优化 资源在silverlight中存在形式: Resource -- 资源会被打包在程序集内部 Content--资源会被打包在Xap包里面 None--资源既不会被集成到程序集内,也不会打包到xap包中.不过我们可以通过设置CopyToOutputDirectory选项让其自动拷贝到xap包所在目录. Resource和Content两种缺点是造成xap包很大,一次性下载到客户端比较慢.None能生成最小的xap包,资源通

一起谈.NET技术,从.NET中委托写法的演变谈开去(中):Lambda表达式及其优势

在上一篇文章中我们简单探讨了.NET 1.x和.NET 2.0中委托表现形式的变化,以及.NET 2.0中匿名方法的优势.目的及注意事项.那么现在我们来谈一下.NET 3.5(C# 3.0)中,委托的表现形式又演变成了什么样子,还有什么特点和作用. .NET 3.5中委托的写法(Lambda表达式) Lambda表达式在C#中的写法是"arg-list => expr-body","=>"符号左边为表达式的参数列表,右边则是表达式体(body).参数列表

一起谈.NET技术,C# 委托,事件和Lambda表达式

关于这个论题,Delegates, Events, and Lambda Expressions 对此有比较深入的分析,可以参考.C# vs C++之一:委托 vs 函数指针 比较了委托和C++指针的区别. .NET 中的委托确实和C/C++的函数指针非常相似.它是一个值类型,它包装了一个指向方法的引用.它的作用也是为了能够将方法和变量一样作为参数传递.委托的典型应用是控件的事件处理方法.很显然,一个控件在设计的时候没有办法知道当特定事件发生的时候,需要什么方法来处理,这就需要将方法作为参数传递

一起谈.NET技术,C#中的委托,匿名方法和Lambda表达式

简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个First不仅被编译,并都获得正确答案,且他们的结果一样.如果你对此感到困惑,那么请继续看这篇文章. class Customer { public int ID { get; set; } public static bool Test(Customer x) { return x.ID == 5; }