C#:List<T> 和 Collection<T> 之间的区别(CA1002,不要公开泛型列表)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1232108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: Difference between List<T> and Collection<T> (CA1002, Do not expose generic lists)
提问by Svish
Tried to run Run Code Analysis on a project here, and got a number of warnings that said something like this:
尝试在此处的项目上运行运行代码分析,并收到许多警告,内容如下:
CA1002 : Microsoft.Design : Change 'List<SomeType>' in 'SomeClass.SomeProtectedOrPublicProperty' to use Collection, ReadOnlyCollection or KeyedCollection
CA1002:Microsoft.Design:将“ SomeClass.SomeProtectedOrPublicProperty”中的“List< SomeType>”更改为使用 Collection、ReadOnlyCollection 或 KeyedCollection
Why should I use Collection<T>
instead of List<T>
? When I look at the msdn documentation, they seem almost equal. After reading the error help for the warning, I found that
为什么我应该使用Collection<T>
而不是List<T>
?当我查看 msdn 文档时,它们似乎几乎相等。在阅读了警告的错误帮助后,我发现
System.Collections.Generic.List(T)_is a generic collection designed for performance not inheritance and, therefore, does not contain any virtual members.
System.Collections.Generic.List(T)_是为性能而非继承而设计的泛型集合,因此不包含任何虚拟成员。
But what does this really mean? And what should I be doing instead?
但这究竟意味着什么?而我应该做什么呢?
Should I keep using List<T>
internally, and then in the properties return a new Collection<T>(someList)
instead? Or should I just start using Collection<T>
instead of List<T>
?
我应该继续在List<T>
内部使用,然后在属性中返回一个new Collection<T>(someList)
吗?还是我应该开始使用Collection<T>
而不是List<T>
?
采纳答案by Rob Levine
In short, the generic list does not have virtual methods for Add, Remove etc, as it was designed to be fast, not extensible. This means that you cannot swap this concrete implementation out for a useful subclass (even though you can subclass it as it is not sealed).
简而言之,泛型列表没有用于 Add、Remove 等的虚方法,因为它被设计为快速的,不可扩展的。这意味着您不能将这个具体实现换成有用的子类(即使您可以将它子类化,因为它不是密封的)。
Therefore, by exposing the List itself, you can never extend your collection to track add or remove operations (for example) without breaking the public contract of the class.
因此,通过公开 List 本身,您永远无法扩展您的集合以跟踪添加或删除操作(例如),而不会破坏类的公共契约。
By exposing your collection as an IList or some-such, you can still use the List as the actual backing-store, but you retain future extensibility as you can swap out the concerete implementation later without changing the public contract of your class.
通过将您的集合公开为 IList 或类似的东西,您仍然可以使用 List 作为实际的后备存储,但您保留了未来的可扩展性,因为您可以稍后在不更改类的公共契约的情况下换出具体的实现。
回答by Simon P Stevens
Collection
exposes some virtual members (insert, remove, set, clear) that you can override and provide additional functionality (such as notification events) when the collection is changed.
Collection
公开一些虚拟成员(插入、删除、设置、清除),您可以在更改集合时覆盖这些成员并提供附加功能(例如通知事件)。
You may not need this now, but it is a common requirement for classes that contain collections, so it's best to plan for it in advance. Because Collection
is designed with extensibility in mind it's very flexible. If in the future you decide you need some extra feature in the collection you can just extend it without any change to the public interface of the class. If you had used a list, you would have had to change it to a collection which means it would have broken all of the callers of your class because they would have to be changed to use lists to.
您现在可能不需要它,但它是包含集合的类的常见要求,因此最好提前计划。因为Collection
在设计时考虑了可扩展性,所以它非常灵活。如果将来您决定在集合中需要一些额外的功能,您可以扩展它而无需对类的公共接口进行任何更改。如果您使用了列表,则必须将其更改为集合,这意味着它会破坏类的所有调用者,因为必须将它们更改为使用列表。
List
on the other hand is designed with performance in mind, so should only be used in specific cases where performance is very important. Because it is not extensible future changes to anything using a list will break everything else dependant on it. Normally List
should only be used internally within very low level classes and not exposed to anything to reduce the chance of future breaking changes.
List
另一方面,在设计时考虑了性能,因此只应在性能非常重要的特定情况下使用。因为它是不可扩展的,未来对使用列表的任何更改都会破坏依赖于它的所有其他内容。通常List
应该只在非常低级别的类内部使用,并且不暴露于任何东西以减少未来破坏性更改的机会。