B.1 接口

  几乎所有要学习的接口都位于 System.Collections.Generic 命名空间。图B-1展示
了.NET4.5以前主要接口间的关系,此外还将非泛型的 IEnumerable 作为根接口包括了进来。为
避免图表过于复杂,此处没有包含.NET 4.5的只读接口。


  正如我们已经多次看到的,最基础的泛型集合接口为 IEnumerable<T> ,表示可迭代的项的
序列。 IEnumerable<T> 可以请求一个 IEnumerator<T> 类型的迭代器。由于分离了可迭代序列
和迭代器,这样多个迭代器可以同时独立地操作同一个序列。如果从数据库角度来考虑,表就是
IEnumerable<T> ,而游标是 IEnumerator<T> 。本附录仅有的两个可变(variant)集合接口
为.NET 4中的 IEnumerable<out T> 和 IEnumerator<out T> ;其他所有接口的元素类型值均
可双向进出,因此必须保持不变。


  接下来是 ICollection<T> ,它扩展了 IEnumerable<T> ,添加了两个属性( Count 和
IsReadOnly )、变动方法( Add 、 Remove 和 Clear )、 CopyTo (将内容复制到数组中)和 Contains
(判断集合是否包含特殊的元素)。所有标准的泛型集合实现都实现了该接口。


  IList<T> 全都是关于定位的:它提供了一个索引器、 InsertAt 和 RemoveAt (分别与 Add
和 Remove 相同,但可以指定位置),以及 IndexOf (判断集合中某元素的位置)。对 IList<T>
进行迭代时,返回项的索引通常为0、1,以此类推。文档里没有完整的记录,但这是个合理的假设。
同样,通常认为可以快速通过索引对 IList<T> 进行随机访问。


  IDictionary<TKey, TValue> 表示一个独一无二的键到它所对应的值的映射。值不必是唯
一的,而且也可以为空;而键不能为空。可以将字典看成是键/值对的集合,因此
IDictionary<TKey, TValue> 扩展了 ICollection<KeyValuePair<TKey, TValue>> 。获
取值可以通过索引器或 TryGetValue 方法;与非泛型 IDictionary 类型不同,如果试图用不存
在的键获取值, IDictionary<TKey, TValue> 的索引器将抛出一个 KeyNotFoundException 。
TryGetValue 的目的就是保证在用不存在的键进行探测时还能正常运行。


  ISet<T> 是.NET 4新引入的接口,表示唯一值集。它反过来应用到了.NET 3.5中的
HashSet<T> 上,以及.NET 4引入的一个新的实现—— SortedSet<T> 。


  在实现功能时,使用哪个接口(甚至实现)是十分明显的。难的是如何将集合作为API的一
部分公开;返回的类型越具体,调用者就越依赖于你指定类型的附加功能。这可以使调用者更轻
松,但代价是降低了实现的灵活性。我通常倾向于将接口作为方法和属性的返回类型,而不是保
证一个特定的实现类。在API中公开易变集合之前,你也应该深思熟虑,特别是当集合代表的是
对象或类型的状态时。通常来说,返回集合的副本或只读的包装器是比较适宜的,除非方法的全
部目的就是通过返回集合做出变动。

猜你喜欢

转载自www.cnblogs.com/kikyoqiang/p/10182564.html
今日推荐