在.NET 2.0+中,使用集合(Collection)相比于List(Of T)有哪些优势?

8

我曾经有一个开发者问我为什么在很多地方都使用List... 我思考了一会儿... 但无法给出一个确定的答案。

如果你继承集合基类来扩展而不是使用List(Of T) - 你会得到什么优势?或者说 - 你不能用List做什么?

5个回答

4

使用泛型列表可以提高性能。

请参考以下问题:

C# 泛型是否有性能优势?

引用自MSDN

使用 List<(Of <(T>)>) 类的类型特定实现,而不是使用 ArrayList 类或编写自己的强类型包装集合,这对你很有好处。原因是你的实现必须做.NET Framework已经为你做的事情,而公共语言运行时可以共享Microsoft中间语言代码和元数据,而你的实现不能。


1
列表不是线程安全的,也不应该被暴露。你可以使用Collection(Of T)代替(请注意,这与CollectionBase不同),或者简单地公开IList(Of T)或IEnumerable(Of T)。

1

一个通用的List<>被设计用于速度和内部使用。另一方面,通用的Collection<>被设计用于可扩展性。

Collection<>类的优点之一是您可以覆盖几个不同的方法(ClearItems()、InsertItem()、RemoveItem()和SetItem())。另一方面,通用的List<>类型提供的没有任何可以被覆盖的方法。

这为什么很重要呢?例如,假设未来的需求要求在将项目添加到集合时引发ItemAdded事件。如果您使用了List<>类型,则选项不多。但是,如果您使用了Collection<>类,则可以公开新的ItemAdded事件并覆盖InsertItem()方法,以便在添加项目时引发ItemAdded事件。


1

类型转换需要时间,并且在使用泛型时会被防止。如果您使用List(Of T),则无需进行类型转换,因为它将是一个强类型的集合。如果您使用ArrayList,则需要从Object向您自己的类型和反向转换,这会导致额外的开销。

此外,您可以防止在编译时无法检测到的类型转换问题。(例如,在应该包含字符串的数组列表中添加一个整数在使用数组列表时不是问题,但在运行时不期望出现整数可能引发无效转换异常。使用泛型列表或集合可以防止出现此类问题,因为代码将无法编译。)

希望这有所帮助。


0
从 Collection(Of T) 继承是 Microsoft 推荐的。List(Of T) API 不能保证在不同版本中保持相同。因此,如果您在公共接口中使用 List(Of T),则在新版本的 CLR 上运行时可能会导致代码中断。
BCL 设计师之一 Krzysztof Cwalina 对 List<T> 有这样的看法:
为什么我们不建议在公共API中使用List<T>?
我们不建议在公共API中使用List<T>,原因有两个。
首先,List<T>不是设计用于扩展的。也就是说,您无法覆盖任何成员。例如,这意味着从属性返回List<T>的对象将无法在集合修改时得到通知。Collection<T>允许您覆盖SetItem受保护成员以在添加新项或更改现有项时获得“通知”。
其次,List<T>具有许多在许多情况下都不相关的成员。我们认为List<T>对于公共对象模型来说过于繁琐。想象一下ListView.Items属性返回带有所有丰富内容的List<T>。现在,看一下实际的ListView.Items返回类型;它要简单得多,类似于Collection<T>或ReadOnlyCollection<T>。 来源

你能提供这个微软建议的链接吗?我怀疑基础类在未来版本的框架中是否能被更改。 - aku
同时,CLR 不会影响 BCL,那么它怎么可能会影响 List<T> 呢? - aku
微软一直以来都有维护版本兼容性的历史。我认为对于 List(Of T) 的破坏性更改是极不可能的。 - ScottS
感谢您的参考。这似乎是合理的建议,但它并没有暗示如果您使用List(Of T),未来版本的.Net会破坏您的代码。 - ScottS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接