C#:List< T>之间的差异

C#: Difference between List<T> and Collection<T> (CA1002, Do not expose generic lists)

本问题已经有最佳答案,请猛点这里访问。

尝试在此处对一个项目运行运行代码分析,并收到了一些警告,这些警告如下所示:

CA1002 : Microsoft.Design : Change 'List' in 'SomeClass.SomeProtectedOrPublicProperty' to use Collection, ReadOnlyCollection or KeyedCollection

为什么要用Collection而不是List?当我查看msdn文档时,它们看起来几乎相等。在阅读了警告的错误帮助之后,我发现

System.Collections.Generic.List(T)_is a generic collection designed for performance not inheritance and, therefore, does not contain any virtual members.

但这到底意味着什么?我应该做什么呢?

我应该在内部继续使用List,然后在属性中返回new Collection(someList)?或者我应该开始使用Collection而不是List


简而言之,通用列表没有用于添加、删除等的虚拟方法,因为它被设计为快速、不可扩展。这意味着您不能将这个具体的实现换成一个有用的子类(即使您可以将它子类化,因为它不是密封的)。

因此,通过公开列表本身,在不破坏类的公共约定的情况下,永远不能扩展集合来跟踪添加或删除操作(例如)。

通过将集合公开为IList或其他类似的类型,您仍然可以将该列表用作实际的后备存储,但是您可以保留将来的扩展性,因为您可以稍后交换concerte实现,而不必更改类的公共约定。


Collection公开了一些虚拟成员(insert、remove、set、clear),您可以在集合更改时覆盖这些虚拟成员并提供其他功能(如通知事件)。

现在您可能不需要这样做,但对于包含集合的类来说,这是一个常见的需求,因此最好提前计划。因为Collection在设计时考虑了可扩展性,所以它非常灵活。如果将来您决定在集合中需要一些额外的特性,您可以在不更改类的公共接口的情况下扩展它。如果使用了列表,则必须将其更改为集合,这意味着它将破坏类的所有调用方,因为必须将它们更改为使用列表。

另一方面,List的设计考虑了性能,因此只应在性能非常重要的特定情况下使用。因为它是不可扩展的,将来对任何使用列表的内容所做的更改都会破坏依赖于它的所有其他内容。通常情况下,List只应在极低级别的类内部使用,不应暴露在任何情况下,以减少未来突破性变化的机会。