C#:List <t>和Collection <t>之间的差异(CA1002,不公开通用列表)</t> </t>

时间:2009-08-05 09:24:15

标签: c# collections encapsulation

试图在这里对项目运行运行代码分析,并得到一些警告,上面写着这样的话:

  

CA1002:Microsoft.Design:更改'列表&lt; SomeType &gt;'在' SomeClass.SomeProtectedOrPublicProperty '中使用Collection,ReadOnlyCollection或KeyedCollection

为什么我应该使用Collection<T>代替List<T>?当我查看msdn文档时,它们看起来几乎相同。在阅读警告的错误帮助后,我发现了

  

System.Collections.Generic.List(T)_是一个通用集合,专为性能而非继承而设计,因此不包含任何虚拟成员。

但这究竟意味着什么?我该怎么做呢?

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

2 个答案:

答案 0 :(得分:135)

简而言之,通用列表没有Add,Remove等虚拟方法,因为它被设计为快速,不可扩展。这意味着您无法将此具体实现交换为有用的子类(即使您可以将其子类化,因为它未被密封)。

因此,通过公开List本身,您永远不能扩展您的集合以跟踪添加或删除操作(例如)而不破坏类的公共合同。

通过将您的集合公开为IList或其他类似的东西,您仍然可以使用List作为实际的后备存储,但是您可以保留未来的可扩展性,因为您可以在不更改类的公共合同的情况下更换concerete实现。

答案 1 :(得分:23)

Collection公开了一些虚拟成员(插入,删除,设置,清除),您可以覆盖这些虚拟成员,并在更改集合时提供其他功能(例如通知事件)。

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

另一方面,

List在设计时考虑了性能,因此只应在性能非常重要的特定情况下使用。因为它不可扩展,所以使用列表对任何事物进行更改都会破坏依赖它的所有其他内容。通常情况下List只能在非常低级别的类中内部使用,并且不会暴露于任何内容以减少将来破坏更改的可能性。