前言

  从.NET3.0开始,C#开始一直支持一个新特性:匿名类型。匿名类型由var、赋值运算符和一个非空初始值(或以new开头的初始化项)组成。匿名类型有如下基本特性:

1、既支持简单类型也支持复杂类型。简单类型必须是一个非空初始值,复杂类型则是一个以new开头的初始化项。

2、匿名类型的属性是只读的,没有属性设置器,它一旦倍初始化就不可更改。

3、如果两个匿名类型的属性值相同,那么就任务这两个匿名类型相等。

4、匿名类型可以在循环中用作初始化器。

5、匿名类型支持智能感知。

6、匿名类型也可以拥有方法。  

本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要学习记录以下内容:

  建议26、使用匿名类型储存LINQ查询结果

  建议27、在查询中使用Lambda表达式

  建议28、理解延迟求值和主动求值之间的区别

建议26、使用匿名类型储存LINQ查询结果

  我们直接来看一个简单的实例吧,假如现在有一个公司Company的实体类,然后又有一个人员的Person类,现在需要将Person类中的Name和Company类中的Name进行关联,而形成一个新的类型。

Compay类

  1. public class Company
  2. {
  3. public int ComparyId { get; set; }
  4.  
  5. public string Name { get; set; }
  6. }

Person类

  1. public class Person
  2. {
  3. public int PersonId { get; set; }
  4.  
  5. public string Name { get; set; }
  6.  
  7. public int CompanyId { get; set; }
  8. }

简单初始化数据

  1. List<Company> companyList = new List<Company>() {
  2. new Company(){ComparyId=, Name="MicroSoft"},
  3. new Company(){ComparyId=, Name="SamSung"}
  4. };
  5. List<Person> personList = new List<Person>() {
  6. new Person(){ PersonId=,Name="aehyok",CompanyId=},
  7. new Person(){ PersonId=,Name="aehyok",CompanyId=},
  8. new Person(){ PersonId=,Name="aehyok",CompanyId=},
  9. new Person(){ PersonId=,Name="aehyok",CompanyId=},
  10. };

下面来看最重要的部分

  1. var personWithCompany = from person in personList
  2. join company in companyList
  3. on person.CompanyId equals company.ComparyId
  4. select new { PersonName = person.Name, CompanyName = company.Name };

其中new之前的代码是Linq关键字,new之后的代码就是匿名类型的初始化项。该匿名类型包含两个属性:PersonName和CompanyName。

  1. foreach(var item in personWithCompany)
  2. {
  3. Console.WriteLine(string.Format("{0}\t:{1}", item.PersonName, item.CompanyName));
  4. }
  5. Console.ReadLine();

调用结果如下所示

建议27、在查询中使用Lambda表达式

Linq实际上是基于扩展方法和lambda表达式的,理解了这一点就不难理解Linq。任何Linq查询都能通过调用扩展方法的方式来替代。下面我们将建议26中的查询语句进行修改

修改之前

  1. var personWithCompany = from person in personList
  2. join company in companyList
  3. on person.CompanyId equals company.ComparyId
  4. select new { PersonName = person.Name, CompanyName = company.Name };

修改之后

  1. var personWithCompany = from person in personList
  2. select new { PersonName = person.Name, CompanyName = person.CompanyId == ? "MicroSoft" : "SamSung" };

当然还有另外一种方式

  1. var personWithCompany = personList.Select(person => new { PersonName = person.Name, CompanyName = person.CompanyId == ? "MicorSoft" : "SamSung" });

针对LINQ设计的扩展方法大多应用了泛型委托。System命名空间定义了泛型委托Action、Func、Predicate。可以这样理解这三个委托:Action用于执行一个操作,所以它没有返回值,Func用于执行一个操作并返回一个值,Predicate用于定义一组条件并判断参数是否符合条件。Select扩展方法接受的就是一个Func委托,而Lambda表达式其实就是一个简介的委托,运算符“=>”左边代表的是方法的参数,右边的是方法体。

下面我们再来举个简单的小例子,调用Where扩展方法,查找出“SamSung”公司的员工

  1. var personWithCompany = personList.Select(person => new { PersonName = person.Name, CompanyName = person.CompanyId == ? "MicorSoft" : "SamSung" });
  2. foreach (var item in personWithCompany.Where(pItem => pItem.CompanyName == "SamSung"))
  3. {
  4. Console.WriteLine(item.PersonName);
  5. }

建议28、理解延迟求值和主动求值之间的区别

我们先继续看一个简单的小例子:

  1. static void Main(string[] args)
  2. {
  3. List<int> list = new List<int>() { , , , , , , , , , };
  4. var temp1 = from c in list where c > select c;
  5. var temp2 = (from c in list where c > select c).ToList<int>();
  6. list[] = ;
  7. Console.Write("temp1:");
  8. foreach (var item in temp1)
  9. {
  10. Console.Write(item.ToString());
  11. }
  12. Console.Write("\ntemp2:");
  13. foreach (var item in temp2)
  14. {
  15. Console.Write(item.ToString());
  16. }
  17. Console.ReadLine();
  18. }

这代码很简单,看执行结果

在延迟求值的情况下,只是定义了一个查询,而且不是立刻执行。对查询结果的访问每次都会遍历原集合。如上文中对于temp1的迭代,在迭代之前,我们修改了list[0]的值,可以看到,修改直接影响了迭代的输出。对查询调用ToList、ToArray等方法,将会使其立即执行,由于对list[0]的修改是在temp2查询之后进行的,所以针对list[0]的修改不会影响到temp2的结果。

在使用Linq to SQL时,延迟求值能够带来显著的性能提升。举个例子:如果定义了两个查询:而且采用延迟求值,CLR会合并两次查询并生成一个最终的查询。

英语小贴士

1、Mineral water——矿泉水      beer——啤酒

2、May I see your passport, please?——我能看一下你的护照吗?  Here is my passport / Here it is.——这是我的护照。

3、What‘s the purpose of your visit?——旅行目的为何? Sightseeing(Businese).——观光(公务)

4、Do you have a return ticket to Taiwan?——是否有台湾回程机票?  Yes, here it is.——这是我的回程机票

5、How long will you be staying in the United States?——5 days.

6、How much money do you have with you?——你随身携带多少现金?  I have 800 dollars.——大约800元

7、Where are you staying?——将在那儿住宿? I will stay at Boston Hotel.——我将住在波士顿饭店。

8、I’m just passing through.——我只是过境而已。

9、I am leaving for Geneva tonight.——今晚即动身前往日内瓦。

作者:aehyok

出处:http://www.cnblogs.com/aehyok/

感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,那不妨点个推荐吧,谢谢支持:-O。

编写高质量代码改善C#程序的157个建议[匿名类型、Lambda、延迟求值和主动求值]的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]

    前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议13.为类型输出格式化字符串 建议14.正确实现浅拷贝和深 ...

  2. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

  3. 读书--编写高质量代码 改善C#程序的157个建议

    最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...

  4. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试

    建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...

  5. 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本

    建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...

  6. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  7. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

  8. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  9. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...

随机推荐

  1. mysql、sql server、oracle数据库分页查询及分析(操作手册)

    1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...

  2. NoSql之旅--Cassandra安装篇(一)

    有点迷茫了,头脑中只想起来一句话,"那就去学习吧". 我负责的项目中有一部分用到了Cassandra,当时也看过点,但是并没有太深入的了解,既然"学习劲头"正足 ...

  3. Shell basic1

    A shell script is a text file that typically begins with a shebang, as follows: #!/bin/bash /bin/bas ...

  4. css3中box-flex的使用

    语法: box-flex:<number> 其中number取值:使用浮点数指定对象所分配其父元素剩余空间的比例.设置或检索伸缩盒对象的子元素如何分配其剩余空间. html代码: < ...

  5. UESTC 915 方老师的分身II --最短路变形

    即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大 ...

  6. POJ 1195 Mobile Phones

    树状数组,开始的时候wa了,后来看看,原来是概率论没学好,以为求(L,B) - (R,T) 矩阵内的和只要用sum(R+1,T+1) - sum(L,B) 就行了,.傻x了.. 必须 sum(R,T) ...

  7. [反编译U3D]Decompile Unity Resources

    工具说明 反编译unity project资源文件,包括ios,android,pc等平台资源,仅供学习使用! 以下工具任选其一,未有特殊说明是可以同时提取unity3.x,unity4.x,unit ...

  8. Flash剪贴板功能

    做JS的都知道,如果不考虑浏览器的兼容问题,其实,JS本身的window.clipboardData对象是可以做到复制内容到剪贴板的功能,但除了IE浏览器,FF和Chrome浏览器都不支持.现在为了浏 ...

  9. 关于软件测试人员能力模型的建立(from知乎)

    转自: http://www.zhihu.com/question/20254092 测试思维方面:1.测试基础理论(测试流程.测试的基础知识)2.测试用例设计方法论(黑盒.白盒)3.软件质量体系(建 ...

  10. .project sturcture和Project Structure 无论是按快捷键或者是从files中打开都不显示

    project sturcture和Project Structure 无论是按快捷键或者是从files中打开都不显示 event log中报:IllegalArgumentException:Mul ...