C#:List <T>和Collection <T>之间的区别(CA1002,不要公开通用列表)

试图在这里运行一个项目的运行代码分析,并得到了一些这样的警告:

CA1002:Microsoft.Design:更改“ SomeClass.SomeProtectedOrPublicProperty ”中的“List < SomeType >”以使用Collection,ReadOnlyCollection或KeyedCollection

为什么我应该使用Collection<T>而不是List<T> ? 当我看到msdn文档时,他们看起来几乎是平等的。 在阅读警告的错误帮助后,我发现

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

但是这是什么意思呢? 我该怎么做呢?

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

简而言之,通用列表没有Add,Remove等虚拟方法,因为它被devise得很快,不可扩展。 这意味着你不能把这个具体的实现交换成一个有用的子类(尽pipe你可以inheritance它,因为它不是密封的)。

因此,通过暴露列表本身,您不能扩展您的集合来跟踪添加或删除操作(例如),而不会破坏该类的公共契约。

通过将你的集合公开为IList或者某些类似的东西,你仍然可以使用List作为实际的后备存储,但是你可以保留将来的扩展性,因为你可以在不改变你的类的公共契约的情况下换掉后续的实现。

Collection暴露了一些虚拟成员(插入,删除,设置,清除),您可以重写并在集合发生更改时提供附加function(例如通知事件)。

现在你可能不需要这个了,但是对于包含集合的类是一个常见的需求,所以最好事先计划一下。 因为Collection的devise考虑到了可扩展性,所以它非常灵活。 如果将来您决定在集合中需要一些额外的function,则可以对其进行扩展,而无需对该类的公共接口进行任何更改。 如果你已经使用了一个列表,你将不得不将其更改为一个集合,这意味着它将打破所有的类的调用者,因为他们将不得不被改为使用列表。

另一方面, List是考虑到性能而devise的,因此只能在性能非常重要的特定情况下使用。 因为它不是可扩展的,所以使用列表的任何事情都会破坏一切依赖它的东西。 通常情况下, List只能在非常低级别的内部使用,而不能暴露于任何事物,以减less未来突变的可能性。