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

建议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 = 0, Name = "Micro" },
                new Company(){ ComanyID = 1, Name = "Sun" }
            };
            //为了演示需要personList并不从数据库读取,而是直接赋值
            List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "Mike", CompanyID = 1 },
                new Person(){ Name = "Rose", CompanyID = 0 },
                new Person(){ Name = "Steve", CompanyID = 1 }
            };

            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个建议》陆敏技

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LINQ to SQL语句(1)之Where 2 Where操作 2 1.简单形式: 2 2.关系条件形式: 2 3.First()形式: 3 LINQ to SQL语句(2)之Select/Distinct 3 1.简单用法: 4 2.匿名类 形式: 4 3.条件形式: 5 4.指定类 形式: 6 5.筛选形式: 6 6.shaped形式(整形类): 6 7.嵌套类形式: 7 8.本地方法调用 形式(LocalMethodCall): 7 9.Distinct形式: 8 LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg 9 1.简单形式: 9 2.带条件形 式: 9 1.简单形式: 10 2.映射形式: 10 3.元素 : 11 1.简单形式: 11 2.映射形式: 11 3.元素: 11 1.简单形式: 12 2.映射形式: 12 3.元素: 12 LINQ to SQL语句(4)之Join 13 Join操作符 13 1.一对多关系(1 to Many): 13 2.多对多关系(Many to Many): 14 3.自联接关系: 15 1.双向联接(Two way join): 15 2.三向联接(There way join): 16 3.左外部联接(Left Outer Join): 17 4.投影的Let赋值(Projected let assignment): 17 5.组合键(Composite Key): 18 6.可为null/不可为null的键关系 (Nullable/Nonnullable Key Relationship): 19 LINQ to SQL语句(5)之Order By 19 Order By操作 19 1.简单形式 19 2.带条件形式 20 3.降序排序 20 4.ThenBy 20 5.ThenByDescending 22 6. 带GroupBy形式 22 LINQ to SQL语句(6)之Group By/Having 23 Group By/Having操作符 23 1.简单形式: 23 2.Select匿名类 : 24 3.最大 值 25 4.最小 值 26 5.平均 值 26 6.求和 26 7.计数 27 8.带条件计数 27 9.Where限制 28 10.多列(Multiple Columns) 28 11.表达式(Expression) 29 LINQ to SQL语句(7)之Exists/In/Any/All/Contains 29 Exists/In/Any/All/Contains操作符 29 Any 29 1.简单形式: 29 2.带条件形式: 30 All 30 Contains 31 1.包含一个对象: 31 2.包含多个值: 32 LINQ to SQL语句(8)之Concat/Union/Intersect/Except 32 Concat/Union/Intersect/Except操作 32 Concat(连接) 32 1.简单形式: 33 2.复 合形式: 33 Union(合并) 33 Intersect(相交) 34 Except(与非) 34 LINQ to SQL语句(9)之Top/Bottom和Paging和SqlMethods 35 Top/Bottom操作 35 Take 35 Skip 35 TakeWhile 36 SkipWhile 36 Paging(分页)操作 36 1.索引 36 2.按唯一键排序 36 SqlMethods操作 37 Like 37 已编译查 询操作(Compiled Query) 38 LINQ to SQL语句(10)之Insert 38 插入(Insert)1.简单形式 38 2.一对多 关系 39 3.多对多关系 39 4.使用动态CUD重写(Override using Dynamic CUD) 40 LINQ to SQL语句(11)之Update 41 更新(Update) 41 1.简单形式 41 2.多项更改 41 LINQ to SQL语句(12)之Delete和使用Attach 42 删除(Delete)1.简单形式 42 2.一对多关系 42 3.推理删除(Inferred Delete) 43 使用Attach更新(Update with Attach) 43 LINQ to SQL语句(13)之开放式并发控制和事务 46 Simultaneous Changes开放式并发控制 46 开放式并发(Optimistic Concurrency) 46 1.Implicit(隐式) 48 2.Explicit(显式) 48 LINQ to SQL语句(14)之Null语义和DateTime 49 Null语义 49 1.Null 49 2.Nullable<T>.HasValue 50 日期函数 50 1.DateTime.Year 51 2.DateTime.Month 51 3.DateTime.Day 51 LINQ to SQL语句(15)之String 51 字符串(String) 51 1.字符 串串联(String Concatenation) 52 2.String.Length 52 3.String.Contains(substring) 52 4.String.IndexOf(substring) 52 5.String.StartsWith (prefix) 53 6.String.EndsWith(suffix) 53 7.String.Substring(start) 53 8.String.Substring (start, length) 53 9.String.ToUpper() 54 10.String.ToLower() 54 11.String.Trim() 54 12.String.Insert(pos, str) 54 13.String.Remove(start) 55 14.String.Remove(start, length) 55 15.String.Replace(find, replace) 55 LINQ to SQL语句(16)之对象标识 56 对象标识 56 对象缓存 56 LINQ to SQL语句(17)之对象加载 57 对象加载延迟加载 57 预先加载:LoadWith 方法 58 LINQ to SQL语句(18)之运算符转换 59 1.AsEnumerable:将类转换为泛 IEnumerable 59 2.ToArray:将序列转换为数组 59 3.ToList:将序列转换为 泛列表 59 4.ToDictionary:将序 列转化为字典 60 LINQ to SQL语句(19)之ADO.NET与LINQ to SQL 60 1.连接 61 2.事务 61 LINQ to SQL语句(20)之存储过程 63 1.标量返回 63 2.单一结 果集 64 3.多个可 能形状的单一结果集 65 4.多个结果集 70 5.带输出参数 79 LINQ to SQL语句(21)之用户定义函数 80 1.在Select使用用户定义的标量函数 80 2.在Where从句中 使用用户定义的标量函数 81 3.使用用户定义的表值函数 83 4.以联接方式使用用户定义的表值函数 84 LINQ to SQL语句(22)之DataContext 85 创建和删除数据库 85 数据库验证 88 数据库更改 88 动态查询 89 日志 90 LINQ to SQL语句(23)之动态查询 90 1.Select 91 2.Where 92 LINQ to SQL语句(24)之视图 94 LINQ to SQL语句(25)之继承 96 1.一般形式 97 2.OfType形式 98 3.IS形式 98 4.AS形式 99 5.Cast形式 99 6.UseAsDefault形式 100 7.插入新的记录 101

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值