题
老问题
我的理解是 C# 在某种意义上 HashSet
和 set
类型。我明白什么 HashSet
是。但为什么 set
是一个单独的词吗?为什么不是每组都是 HashSet<Object>
?
新问题
为什么C#没有泛型 Set
类型,类似于 Dictionary
类型?从我的角度来看,我希望拥有一套具有标准查找/添加/删除性能的集合。我不太关心它是用哈希还是其他东西实现的。那么为什么不创建一个集合类来实际实现为 HashSet
在这个版本的 C# 中,但在未来的版本中可能会有所不同?
或者为什么不至少有接口 ISet
?
回答
学习了,感谢以下所有回答的人: ICollection
实现了很多你所期望的 ISet
. 。但从我的角度来看, ICollection
实施 IEnumerable
而集合不必是可枚举的——例如:1 到 2 之间的实数集(甚至可以动态生成集)。我同意这是一个小抱怨,因为“普通程序员”很少需要不可数的集合。
好吧,我想我明白了。 HashSet
绝对应该被称为 Set
但这个词 Set
在某种意义上是保留的。更具体地说,.NET 架构的创建者希望为不同的语言提供一组一致的类(原文如此!)。这意味着标准类的每个名称都不能与 .NET 语言中的任何关键字一致。这个单词 Set
, 然而,在 VB.NET 中使用的实际上是不区分大小写的(是吗?),所以不幸的是,那里没有回旋余地。
谜团已揭开 :)
结语
Alex Y 的新答案。链接到 MSDN 页面 其中描述了即将推出的 .NET 4.0 接口 ISet
它的行为与我认为应该的非常相似,并且是由 HashedSet
. 。好结局。
解决方案
(你原来的问题是关于 set
已得到答复。IIRC,“set”是英语中含义最不同的单词......显然这对计算也有影响。)
我觉得有就好了 HashSet<T>
用这个名字,但我当然欢迎 ISet<T>
界面。鉴于 HashSet<T>
仅在 .NET 3.5 中出现(这本身就令人惊讶),我怀疑我们最终可能会获得更完整的基于集合的类型集合。特别是,相当于 Java 的 LinkedHashSet
, ,它保持插入顺序,在某些情况下会很有用。
公平地说, ICollection<T>
界面实际上涵盖了您想要的大部分内容 ISet<T>
, ,所以也许这不是必需的。但是,您可能会认为集合的核心目的(主要是关于包含,并且只是与能够迭代元素无关)与集合并不完全相同。这很棘手。事实上,一个真正的数学集合可能不是可迭代或可数的——例如,你可以有“1 到 2 之间的实数集合”。如果你有一个任意精度的数值类型,则计数将是无限的,迭代它没有任何意义。
同样,“添加”到集合中的想法并不总是有意义。命名集合时,可变性是一件棘手的事情:(
编辑:好的,回复一下评论:关键字 set
绝不是 Visual Basic 的遗产。这是一个操作 套 财产的价值,vs get
哪个 检索 操作。这与集合作为运算的概念无关。
想象一下,关键词实际上是 fetch
和 assign
, ,例如
// Not real code!
public int Foo
{
fetch
{
return fooField;
}
assign
{
fooField = value;
}
}
那里的目的明确吗?现在 真实的 C# 中的等价物就是
public int Foo
{
get
{
return fooField;
}
set
{
fooField = value;
}
}
所以如果你写:
x = y.Foo;
这将使用 get
财产的一部分。如果你写:
y.Foo = x;
这将使用 set
部分。
这样是不是更清楚了?
其他提示
没有Set <T>
。这个 BCL团队博客文章有很多关于HashSet的详细信息,包括一个关于在名称中包含hash的完全结论性的讨论。我怀疑不是BCL团队中的每个人都喜欢使用名称HashSet <=>的决定。
set
是自1.0版以来一直存在的C#语言关键字。 Is用于定义属性的值赋值部分(get
用于实现属性的值读取部分)。在这种情况下,您应该将“set”一词理解为动词,如设置值。
HashSet<T>
是集合的数学概念的特定实现。它最初是在.NET 3.5中引入的。 BCL团队的这篇博客文章更多地介绍了其背后的原因,以及为什么名称为Set<T>
而不仅仅是<=>的一些线索: http://blogs.msdn.com/bclteam/archive/2006/11/09/introducing -hashset叔KIM-hamilton.aspx 。
在<=>的情况下,您应该将'set'这个词理解为名词。
Set是VB.NET中的保留关键字(它相当于在C#中设置)。 VB.NET可以使用与关键字同名的类/方法/ etc,但它们必须在方括号之间编写,这很难看:
Imports Wintellect.PowerCollections 'PowerCollections contains a class called Set'
Public Class Test
Private _myValue As Integer
Public Property MyValue() As Integer
Get
Return _myValue
End Get
Set ' Set as keyword'
_myValue = value
End Set
End Property
Public Function X As [Set](Of Integer)
Dim a As New [Set](Of Integer) ' Set as class'
Return a
End Function
End Class
啊,对了,我现在明白你的问题了
不确定我能否 100% 看到需要 ISet<T>
.
我想问题是你认为哪些行为是集合的基本行为?
是添加、删除、包含等吗?如果是这样那么 ICollection<T>
已经为此提供了一个接口。
如果它是集合操作,例如并集、相交等,那么您是否认为这些操作足够通用,可以抽象为契约式执行?
我不得不说,我不知道这个问题的正确答案 - 我认为这是有争议的,我怀疑 BCL 团队最终可能会在未来的版本中加入类似的内容,但这取决于他们。我个人并不认为它是一个巨大的功能缺失
原帖
BCL 根本没有 Set 集合,至少据我所知没有。
有一些第三方设置库,例如 Iesi.Collections
HashSet<T>
在 .NET 3.5 中引入,用于创建快速集合集合,即您想要一个没有重复项的集合。它还具有典型的集合操作,例如 Union 和 Join。查看 这个链接 来自 HashSet 上的 BCL 团队
您通常会在以前必须使用的地方使用它 List<T>
并在添加时检查是否有重复项。
将项目添加到 HashSet<T>
也可以是 明显更快 比列表
一些进一步的细节:
HashSet 的另一个不错的功能是,如果您尝试添加重复项,它不会抛出异常,它只是无法添加重复条目,这使您不必在每个添加周围放置大量 try.catch 块 - 很好:)
我很确定BCL中没有Set<T>
类,至少在.NET 3.5中(而不是.NET 4.0)。无论如何,你期望这样的课程需要什么?
HashSet<T>
本身只是一个普通的集合数据结构,它使用哈希码(对象的GetHashCode
方法)来比较元素。这只是实现集合类型的有效方式。 (检查相等性的其他方法可能会降低性能。)