【问题标题】:C#: Difference between List<T> and Collection<T> (CA1002, Do not expose generic lists) [duplicate]C#:List<T> 和 Collection<T> 之间的区别(CA1002,不公开通用列表)[重复]
【发布时间】:2010-11-16 22:55:59
【问题描述】:

尝试在此处的项目上运行运行代码分析,并收到许多警告,内容如下:

CA1002:Microsoft.Design:将“SomeClass.SomeProtectedOrPublicProperty”中的“ListSomeType>”更改为使用 Collection、ReadOnlyCollection 或 KeyedCollection

为什么我应该使用Collection&lt;T&gt; 而不是List&lt;T&gt;?当我查看 msdn 文档时,它们似乎几乎相等。在阅读了警告的错误帮助后,我发现

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

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

我是否应该继续在内部使用List&lt;T&gt;,然后在属性中返回new Collection&lt;T&gt;(someList)?还是我应该开始使用Collection&lt;T&gt; 而不是List&lt;T&gt;

【问题讨论】:

标签: c# collections encapsulation


【解决方案1】:

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

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

通过将您的集合公开为 IList 或类似的东西,您仍然可以将 List 用作实际的后备存储,但您可以保留未来的可扩展性,因为您可以稍后换出具体的实现,而无需更改您班级的公共合同.

【讨论】:

  • 仅供参考,Collection&lt;T&gt; 在内部使用 List&lt;T&gt; 实例。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2010-09-28
    • 2014-10-12
    • 2017-11-29
    • 2015-11-06
    • 1970-01-01
    相关资源
    最近更新 更多