用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能够支持我们自定义的,或是其他框架中的集合类型。