简而言之,从概念上讲,包含列表的对象负责拥有存储数据的有效方法,这意味着它应该负责在需要时实例化其列表。
如果对象被设计为表示对象的集合,那么它负责维护它在内部实际使用来存储它们的任何内容,除非目标的一部分是让新对象成为多种类型集合的“包装器”,允许基于内部使用的集合类型进行行为定制。
考虑一个列表。它在内部使用一个数组来存储数据,并根据需要处理所述数组的大小调整以存储新对象。您不必了解列表;从概念上讲,它是一个有序的索引集合,允许插入和删除元素。它可以用链表、红黑树或其他任何东西来实现;这些会对性能和复杂性产生影响。
回到正题。您的对象应该是具有附加属性的列表,应该隐藏其内部数据结构。用户不需要知道那里有一个 List 来保存元素。这意味着您的对象应该知道如何实例化它自己的内部数据结构,并公开调用者用来注入新元素的方法,这些新元素作用于内部列表。
一个例外是“包装器”,它添加了可以应用于任何其他类子集的新功能,并且允许用户指定新的类应该在特定用途中“包装”哪个类是很重要的。一个例子是 BlockingCollection。它增加了阻止正在对集合执行某些并发操作的线程的能力,直到它有效且安全地执行所述操作(例如,如果集合为空,则尝试从 BlockingCollection 获取项目的线程将被阻止,直到另一个线程添加一些东西)。创建时,可以指定 BlockingCollection 使用 IProducerConsumerCollection 接口的特定实现;很可能是同一命名空间中的内置“并发”集合之一,例如 ConcurrentBag、ConcurrentQueue 或 ConcurrentDictionary。即使在这种情况下,也有一个“默认”选项;您可以在不指定要使用的内部 Concurrent 结构的情况下实例化 BlockingCollection 对象,并且该对象将默认为 ConcurrentQueue。