【转】编写高质量代码改善C#程序的157个建议——建议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个建议》陆敏技

posted @ 2017-11-30 17:21  指间的徘徊  阅读(299)  评论(0编辑  收藏  举报