集合<T>类及其用途

Zai*_*sud 25 .net c# collections

我遇到了以下代码:

var collection = new Collection<string>();
Run Code Online (Sandbox Code Playgroud)

我没有看到Collection类使用太多,也找不到太多关于它的用途的信息.查看.NET Framework源代码,它几乎只是List的包装器,因为它存储了List成员字段.它的构造函数如下:

public Collection()
{
  this.items = (IList<T>) new List<T>();
}
Run Code Online (Sandbox Code Playgroud)

它还实现了IList.所以你可以将Collection声明为:

IList<string> collection = new Collection<string>();
Run Code Online (Sandbox Code Playgroud)

对我来说,在功能上等同于创建一个List:

IList<string> collection = new List<string>();
Run Code Online (Sandbox Code Playgroud)

那么你什么时候想在你自己的代码中使用它?我看到它是其他.NET集合的基类,但为什么它们将它作为公共具体(而不是内部和/或抽象)包含在内?


关于可能重复的注释 - 相关问题的答案似乎表明Collection类应该用作基类.我真正要求的不同之处是:

  1. 如果在您自己的代码中使用,为什么不使用List作为基类呢?
  2. 在您自己的代码中实例化一个新的集合代替List真的有意义吗?
  3. 如果真的只是作为基类提供,为什么它不是抽象的

Jen*_*s H 18

我认为MSDN文档本身已经列出了最重要的方面(由我突出显示):

集合类提供受保护的方法可用于 定制其行为当添加和删除项目,清理收集,或设置现有项目的价值.

对实施者的说明

提供此基类是为了使实现者更容易创建自定义集合.鼓励实施者扩展此基类,而不是创建自己的基类.

[编辑ypur更新问题]

1.如果在您自己的代码中使用,为什么不使用List作为基类呢?

Collection<T>提供一些受保护的方法,以便您可以轻松地override执行行为并完全注册您自己的业务逻辑,例如:

  • ClearItems()
  • InsertItem()
  • RemoveItem()
  • SetItem()

List<T> 没有提供它们,几乎没有任何受保护的方法来覆盖行为,这使得定制更难.

2.在您自己的代码中使用List初始化新集合是否真的有意义?

不,不只是为了初始化一些集合.如果您需要它作为实现自己的逻辑的基类,请使用它.

这取决于您自己的业务需求.对于日常开发工作中的几乎所有情况,现有的和众多的集合应该已经提供了您所需要的.有类型安全和无类型集合,线程安全集合,以及您能想到的任何其他内容.

尽管如此,有一天可能需要实现一种集合类型,该集合类型在允许添加/更新/删除其中的任何项目之前执行某些验证检查,或者以特定方式处理仅在稀疏填充的列表中移动到下一项目.你永远不知道顾客可能有什么想法.

在这种情况下,创建自己的集合类型可能会有所帮助.

  • 抽象类可以有非抽象的虚方法,所以你所说的可以通过抽象类来完成. (2认同)

Fre*_*els 9

集合(T)类是一大堆其他集合类的基类.该列表类,是对速度进行了优化的一类,而集合类,是专为可扩展性.

当你看到成员时Collection(T),你会发现它包含了一些类没有的其他受保护的虚拟方法(比如InsertItem)List(T).

实际上,我已经创建了Collection类的一个实例.我想我只会将此类型用作方法签名中的参数,只是为了不将方法与集合的实现紧密耦合(如果可能).

回答你的问题:

  1. 我将Collection(T)用作基类,因为该类的目的是用作其他集合类型的基类.它为您提供更大的灵活性(请参阅受保护的虚拟方法InsertItem,RemoveItem以及SetItem)

  2. 当需要集合时,我会使用List(T)该类的实例 ,因为它针对速度进行了优化.

  3. 实际上,我想知道为什么他们没有把Collection(T) 课程抽象化.


Bas*_*Bas 7

正如Krzysztof Cwalina 所说:

•列表不是为了扩展而设计的.即你不能覆盖任何成员.例如,这意味着在修改集合时,无法通知从属性返回List的对象.Collection允许您覆盖SetItem受保护的成员,以便在添加新项目或更改现有项目时获得"通知".

•列表中有许多成员在许多情况下都不相关.我们说List对于公共对象模型来说太"忙"了.想象一下ListView.Items属性返回List的所有丰富性.现在,看看实际的ListView.Items返回类型; 它更简单,类似于Collection或ReadOnlyCollection.

因此,FxCop的规则CA1002也告诉您不要公开通用列表并改为使用Collection.另请参阅此代码分析团队博客文章,了解有关FxCop规则以及返回Collection而不是List的原因.

因此,对于问题1和2,请参见上文.至于问题三,它不仅仅是作为一个基类.你应该能够实例化它并将其用作返回类型,因此它不是抽象的.


Zai*_*sud 4

我不太喜欢回答自己的问题,但就第三个问题而言,我相信我理解其中的推理。我在查看Bas Paap 的答案中引用的链接时得到了它。

简而言之,Collection 类不是抽象的原因是因为您可能希望自己可以选择稍后从该类派生。同时,您可以将其用作返回类型并直接实例化它。该链接显示了这种情况的代码示例。

我对我认为解决了问题中提出的问题的所有其他答案都投了赞成票。