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

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

  • 即支持简单类型也指出复杂类型。简单类型必须是一个非空初始值,复杂类型则是一个以new开头的初始化项。
  • 匿名类型的属性是只读的,没有属性设置器,它一旦被初始化就不可更改。
  • 如果两个匿名类型的属性值相同,那么就认为这两个匿名类型相等。
  • 匿名类型可以再循环中用作初始化器。
  • 匿名类型支持智能感知。
  • 匿名类型可以拥有方法。

在类型仅仅被当前的代码使用,或者被用于存储某种查询结果的场景中,匿名类型将大有用途。匿名类型是保存LINQ查询结果的最佳搭档。

如下场景:

将Person或Person相关类(如Company)从数据库中取出来,我们需要将Person中的属性Name和根据CompanyID对应起来的Company的属性Name联系起来,形成一个新的类型。这个新的类型也许用于某个UI控件的绑定源,也许用于某个特殊算法的输入。总之,数据库中的格式一旦设计完毕并投入使用,很少会有变动,但是需求却千变万化,实际需求需要创建很多这样的临时类型。如果这临时类型全部使用普通的自定义类型,代码将会膨胀起来变得难以维护。这个时候,匿名类型就派上用场了。

    class Program
{
static void Main(string[] args)
{
//为了演示需要companyList并不从数据库读取,而是直接赋值
List<Company> companyList = new List<Company>()
{
new Company(){ ComanyID = , Name = "Micro" },
new Company(){ ComanyID = , Name = "Sun" }
};
//为了演示需要personList并不从数据库读取,而是直接赋值
List<Person> personList = new List<Person>()
{
new Person(){ Name = "Mike", CompanyID = },
new Person(){ Name = "Rose", CompanyID = },
new Person(){ Name = "Steve", CompanyID = }
}; var personWithCompanyList = from person in personList
join company in companyList on person.CompanyID equals company.ComanyID
select new { PersonName = person.Name, CompanyName = company.Name };
foreach (var item in personWithCompanyList)
{
Console.WriteLine(string.Format("{0}\t:{1}", item.PersonName, item.CompanyName));
}
}
} class Person
{
public string Name { get; set; }
public int CompanyID { get; set; }
} class Company
{
public int ComanyID { get; set; }
public string Name { get; set; }
}

输出为:

Mike    :Sun
Rose    :Micro
Steve   :Sun

查看IL代码,可以看见匿名类型在IL中会生成一个类(也称为一个投影)

非匿名类型包括的Equals、GetHashcode、ToString等方法匿名类型都有。并且编译器为我们重载了ToString方法,它返回的是类型的属性即对应的值。

            foreach (var item in personWithCompanyList)
{
Console.WriteLine(item.ToString());
}

输出的结果为:

{ PersonName = Mike, CompanyName = Sun }
{ PersonName = Rose, CompanyName = Micro }
{ PersonName = Steve, CompanyName = Sun }

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

编写高质量代码改善C#程序的157个建议——建议26:使用匿名类型存储LINQ查询结果的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

随机推荐

  1. nagios(centreon)监控lvs

    客户端配置:让nagios账户有权限查看ipvsadminvim /etc/sudoers[root@SSAVL2318 etc]# visodu /etc/sudoers加入 nagios  ALL ...

  2. 减少CXF日志打印

    场景:项目中引用cxf发布服务,服务调用产生的日志实在是太多了,实在是不能忍 官方文档:http://cxf.apache.org/docs/debugging-and-logging.html#De ...

  3. Redis官方文档》持久化

    原文链接 译者:Alexandar Mahone 这篇文章从技术层面描述了Redis持久化,建议所有读者阅读.如果希望更多了解Redis持久化和持久性保障,建议阅读Redis持久化揭秘. Redis ...

  4. linux 定时脚本任务的创建

    参考资料https://my.oschina.net/xsh1208/blog/512810 定时脚本任务创建过程 1. 启动/终止 crontab 服务 一般使用这个命令/sbin/service ...

  5. 如何检测 51单片机IO口的下降沿

    下降沿检测,说白了就是满足这样一个逻辑,上次检测是1,这次检测是0,就是下降沿. 从这个条件可知,要确保能够正确检测到一个下降沿,负脉冲的宽度,必须大于一个检测周期,当负脉冲宽度小于一个检测周期,就有 ...

  6. Lua调用C++带参数的方法

    C++代码: // LuaAndC.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #i ...

  7. php命令执行

    php命令执行通过函来执行外部应用程序,函数有shell_exec(),exec(),system(),passthru() <?php $i = $_GET['cmd']; echo exec ...

  8. 优化深度神经网络(二)优化算法 SGD Momentum RMSprop Adam

    Coursera吴恩达<优化深度神经网络>课程笔记(2)-- 优化算法 深度机器学习中的batch的大小 深度机器学习中的batch的大小对学习效果有何影响? 1. Mini-batch ...

  9. Python not readable

    try: with open('data.txt','w') as f: for each_line in f: print(each_line)except OSError as reason: p ...

  10. Vue 简单的总结三

    一.安装脚手架 1.下载node.js,本文下载版本为node-v8.12.0-x64.msi,一键式安装. 2.安装按成后,打开终端,输入node,可进入node环境(两次ctrl+c退出),如下图 ...