为啥 HashSet<T> 没有实现 ICollection?
Posted
技术标签:
【中文标题】为啥 HashSet<T> 没有实现 ICollection?【英文标题】:Why does HashSet<T> not implement ICollection?为什么 HashSet<T> 没有实现 ICollection? 【发布时间】:2015-09-25 04:52:03 【问题描述】:我将编写一个库来遍历对象图(例如某种序列化)。
您需要判断一个对象是否是遍历中的一个集合,所以ICollection
出现在我的脑海中。 (string
也实现了IEnumerable
)
但是真的很奇怪,Collections 中几乎所有的容器都实现了ICollection
除了HashSet
只实现了ICollection<T>
...
我已经检查了System.Collections
命名空间中几乎所有常见的容器:
ArrayList : IList, ICollection, IEnumerable, ICloneable
BitArray : ICollection, IEnumerable, ICloneable
Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
Queue : ICollection, IEnumerable, ICloneable
SortedList : IDictionary, ICollection, IEnumerable, ICloneable
Stack : ICollection, IEnumerable, ICloneable
Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable, IDeserializationCallback
HashSet<T> : ISerializable, IDeserializationCallback, ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable
LinkedList<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback
List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
Queue<T> : IEnumerable<T>, ICollection, IEnumerable
SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
SortedList<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
SortedSet<T> : ISet<T>, ICollection<T>, IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback
Stack<T> : IEnumerable<T>, ICollection, IEnumerable
这是一个错误吗?还是有什么原因?
【问题讨论】:
我相信this link 与您的问题相关。 .NET 集合层次结构真的很乱。 如果您将 1.1 代码升级到 2.0,那么List<T>
实现 ICollection
可以说可以帮助您替换 ArrayList
的旧用法(可以说让编译器错误指向哪里会更好)您需要升级到ICollection<T>
)。 HashSet<T>
在 3.5 引入之前没有非通用版本,因此支持 ICollection
和其他大多数人的原因之一不存在。
@JonHanna 但是SortedSet<>
是一个更新的类型,它确实实现了非泛型ICollection
?
对应元帖:meta.***.com/questions/293815/…
【参考方案1】:
ICollection
现在远没有 .NET 1.1 那样有用,当时还没有 ICollection<T>
提供更高的类型安全性。很少有人可以用ICollection
做有用的事情而用ICollection<T>
做不到,通常效率和/或类型安全性更高,特别是如果为那些可能想要对集合做某事的情况编写通用方法时不同的元素类型。
这虽然引出了一个问题,为什么List<T>
之类的人确实 实现了ICollection
。但是当List<T>
与.NET 2.0 一起引入时,所有遗留代码都使用ICollection
和ArrayList
,而不是ICollection<T>
和List<T>
。将代码升级为使用List<T>
而不是ArrayList
可能会很痛苦,尤其是如果这意味着必须立即更改ICollection
的所有用法,使用ICollection<T>
或者更糟糕的是,因为一种方法而加倍被List<T>
击中,也被其他非泛型集合击中,因此每个版本都需要该方法的版本。实施 ICollection
让人们可以更加零碎地利用通用集合,从而简化了升级路径。
HashSet<T>
出来的时候,泛型已经使用了三年了,并且没有框架提供以前的非泛型哈希集类型,所以升级的痛苦更少,因此更少支持ICollection
的动机。
【讨论】:
ICollection 对于确定对象是有限非惰性集合非常有用。大多数人只是使用 IEnumerable 来确定对象是某种集合,但 IEnumerable 可以是惰性的和/或无限的。所以 ICollection 是几乎所有有限非惰性集合都支持的最小接口。很烦人的是很少有像 HashSet以上是关于为啥 HashSet<T> 没有实现 ICollection?的主要内容,如果未能解决你的问题,请参考以下文章