【IT168技术文档】
在过去的2个月里,我发表了一系列贴子,讨论作为Visual Studio和.NET框架Orcas版本一部分发布的一些新的语言特性。这里是这个系列里前4个贴子的链接:
今天的贴子讨论我这个语言系列的最后一个新特性:匿名类型。
什么是匿名类型(Anonymous Types)?
匿名类型是C#和VB的方便语言特性,它允许开发人员在代码内简明地定义行内CLR类型,而不用显式地对类型定义一个正式的类声明。
匿名类型在使用LINQ做查询,转换/投影/构形数据时尤其有用。
匿名类型的例子
在我以前的查询句法贴子里,我示范了你可以通过投影来转换数据。这个LINQ的强有力的特性允许你对一个数据源(不管这个数据源是数据库,XML文件还是内存中的集合)做查询操作,然后对查询数据的结果构形成与原先数据源不同的结构或格式。
在我以前的查询句法贴子里,我定义了一个用来代表我转换过后的产品数据的MyProduct类。通过显式地定义MyProduct类,我就有了一个正式的CLR类型契约,我可以很容易地用它来把我自定义结构的产品结果在web服务间或我的应用解决方案中的多个类和程序集间传递。
但有的时候,我只想要在我当前的代码范围内查询和操作数据,我不想要另外正式地定义一个类来代表我的数据,才可以操作数据。在这种情形下,匿名类型非常有用,因为它们允许你在你的代码内,简明地定义一个新类型在行内使用。
例如,假设我使用Orcas中的LINQ到SQL对象关系映射器设计器对Northwind数据库建模,生成下列的类:
然后我就可以使用下列代码来对数据库里的产品数据进行查询,使用LINQ的投影/转换功能将数据结果定制构形成与上面的Product类有所不同的东西。但不是用一个显式定义的MyProduce类来代表从数据库获取的数据行,而是用匿名类型的特性来隐式地定义一个含4个属性的新类型来代表我定制构形的数据,象这样:
在上面的代码里,作为LINQ表达式select子句的一部分,我声明了一个匿名类型,然后由编译器自动生成带4个属性(Id, Name, UnitPrice 和 TotalRevenue)的匿名类型,这些属性的名称和类型是从查询的构形中推断出来的。
然后我使用了C#中的var这个新关键词来指代从LINQ表达式返回的这个匿名类型的 IEnumerable<T> 序列,还在后面代码的foreach语句里,对这个序列进行循环时,用var来指代其中的每个匿名类型实例。
尽管这个句法给了我动态语言一样的灵活性,我还保留了强类型语言的好处 - 包括 Visual Studio中的编译时检查和代码intellisense支持。例如,注意上面,我是如何对返回的产品序列做foreach的,对从LINQ查询推断出的带自定义属性的匿名类型,我还能得到完整的代码intellisense和编译检查。