日期:2014-05-20  浏览次数:20905 次

用LINQ操作内存中的集合
[color=#FF00FF][color=#FF00FF]用LINQ操作内存中的集合
LINQ   to   Objects是指用LINQ操作内存中对象的集合的方法。但这是什么意思呢?LINQ   to   Objects支持哪些类型的集合呢?LINQ   to   Objects又能在这些集合上进行什么操作呢?

本节将从介绍能够与LINQ配合使用的集合类型开始,随后给出这些集合类型所支持的LINQ操作。

4.2.1 能够查询什么

可以预料的是,并不是所有的对象都能够使用LINQ   to   Objects进行查询,使用LINQ   to   Objects的首要条件就是将要查询的对象是某种类型的集合。

若想让集合类型能够和LINQ   to   Objects配合使用,那么只要确保其实现了IEnumerable <T> 接口即可。不要忘记,实现了IEnumerable <T> 接口的对象在LINQ中叫做序列。幸运的是在.NET框架中几乎所有的泛型类型的集合都实现了IEnumerable <T> 接口。这也就意味着LINQ   to   Objects天生就能够支持那些你早已熟悉的.NET   2.0集合类型。

接下来就来逐一介绍能够通过LINQ   to   Objects进行查询的集合类型。

1.   数组

包括元素类型为Object在内的所有类型的数组都可以与LINQ   to   Objects配合使用,如代码清单4-2所示。

代码清单4-2 通过LINQ   to   Objects查询元素类型为Object的数组(UntypedArray.csproj)


注意           在第2章中我们已经使用过了ObjectDumper类。ObjectDumper是一个非常有用的辅助类,能够显示对象中的数据,随微软公司的LINQ示例代码提供。在本书所附的可下载的源代码中,也能找到该辅助类。

上述代码显示了数组中元素的类型,并按照名称排序。其输出结果如下:


当然,查询也能够应用在元素为自定义类型的数组上。在代码清单4-3中,程序就基于一个元素类型为Book的数组进行了查询。

代码清单4-3 通过LINQ   to   Objects查询元素为强类型的数组(TypedArray.csproj)


实际上,LINQ   to   Objects能够应用于任何数据类型的数组。LINQ   to   Objects还能够支持其他的一些重要集合类型,例如泛型列表、泛型字典等。

2.   泛型列表

毫无疑问,我们在.NET   2.0中最常用到的集合类型就是List <T> ,LINQ   to   Objects对List <T> 以及其他泛型列表提供了完善的支持。

下面列出了框架所提供的主要泛型列表:

l         System.Collections.Generic.List <T>

l         System.Collections.Generic.LinkedList <T>

l         System.Collections.Generic.Queue <T>

l         System.Collections.Generic.Stack <T>

l         System.Collections.Generic.HashSet <T>

l         System.Collections.ObjectModel.Collection <T>

l         System.ComponentModel.BindingList <T>

代码清单4-4就将前面操作于数组的示例程序改为了操作泛型列表。

代码清单4-4 通过LINQ   to   Objects查询泛型列表


注意到查询语句本身没有作任何的改变,因为无论是数组还是列表都实现了同样的IEnumerable <Book> 接口。而这个接口正是LINQ   to   Objects查询所依赖的全部基础设施。

虽然最常见的是让LINQ与数组或列表配合使用,不过有时候我们也需要查询泛型字典。

3.   泛型字典

与泛型列表类似的是,所有的泛型字典都支持用LINQ   to   Objects进行查询:

l         System.Collections.Generic.Dictionary <TKey,TValue>

l         System.Collections.Generic.SortedDictionary <TKey,   TValue>

l         System.Collections.Generic.SortedList <TKey,   TValue>

泛型字典均实现了IEnumerable <KeyValuePair <TKey,   TValue> > 接口,其中的KeyValuePair结构包含了强类型的Key和Value属性。

代码清单4-5演示了查询一个由整型值作为索引、字符串作为值的字典的方法。

代码清单4-5 通过LINQ   to   Objects查询泛型字典(GenericDictionary.csproj)


上述代码的输出结果将如下所示:


到此为止,我们已经给出了查询中最常见的几种集合。不过,你还可以查询一些其他类型的集合。

4.   字符串

虽然第一眼看上去System.String并不像是个集合,不过它的确实现了IEnumerable   <Char> 接口。因此自然可以使用LINQ   to   Objects对其进行操作——就像操作别的集合类型一样。

注意           在C#中有一个特殊的处理情况,即智能感知将不会自动为System.String给出LINQ相关的扩展方法提示,因为很少有人将System.String作为IEnumerable <Char> 处理。

我们来看一个示例程序。代码清单4-6中的LINQ查询将作用于一个字符串中的各个字符上。

代码清单4-6 通过LINQ   to   Objects查询字符串(String.csproj)


显然,该程序的运行结果是8。

5.   其他集合

这里我们只列出了.NET框架内建的集合类型。不过,你也可以让LINQ   to   Objects与其他任何的实现了IEnumerable <T> 接口的集合配合使用。也就是说,LINQ   to   Objects能够支持我们自定义的,或是其他框架中的集合类型。