为什么有HashSet但没有在C#中设置?

老问题

我的理解是C#在某种意义上具有HashSetset类型。 我理解HashSet是什么。 但为什么set是一个单独的词? 为什么不是每个集合都是HashSet

新问题

为什么C#没有genericsSet类型,类似于Dictionary类型? 从我的角度来看,我希望有一个具有标准查找/添加/删除性能的集合。 我不关心它是用哈希还是别的来实现的。 那么为什么不在这个版本的C#中创建一个实际上被实现为HashSet的集合类,但在将来的版本中可能会有所不同?

或者为什么不至少接口ISet

回答

感谢所有回答如下的人: ICollection实现了很多你对ISet期望。 但是,从我的观点来看, ICollection实现了IEnumerable而集合不必是可枚举的—例如:1到2之间的实数集合(甚至更多,集合可以动态生成)。 我同意这是一个小咆哮,因为“普通程序员”很少需要不可数集。

好吧,我想我明白了。 HashSet绝对意味着被称为Set但在某种意义上保留了Set这个词。 更具体地说,.NET体系结构的创建者希望为不同的语言提供一致的集合(sic!)。 这意味着标准类的每个名称都不得与.NET语言中的任何关键字一致。 然而,在VB.NET中使用了这个词,它实际上是不区分大小写的(是吗?),所以不幸的是那里没有空间。

谜团已揭开 :)

结语

Alex Y的新答案链接到MSDN页面 ,该页面描述了即将推出的.NET 4.0接口ISet ,它的行为与我认为应该HashedSet并由HashedSet实现。 好结局。

(关于set原始问题已得到解答.IIRC,“set”是英语中含义最多的单词……显然这对计算也有影响。)

我认为使用该名称的HashSet很好,但我当然欢迎使用ISet接口。 鉴于HashSet仅在.NET 3.5中出现(这本身就令人惊讶),我怀疑我们最终可能会获得更完整的基于集合的类型集合。 特别是,维护插入顺序的Java的LinkedHashSet的等价物在某些情况下会很有用。

公平地说, ICollection接口实际上涵盖了您在ISet所需的大部分内容,因此可能不需要。 但是,您可能会认为集合的核心目的(主要是关于包容,并且只是切向关于能够迭代元素)与集合不完全相同。 这很棘手。 事实上,一个真正的数学集合可能不是可迭代的或可数的 – 例如,你可以拥有“1到2之间的实数集”。 如果你有一个任意精度的数字类型,计数将是无限的,迭代它将没有任何意义。

同样,“添加”到集合的想法并不总是有意义的。 命名集合时,可变性是一项棘手的事情:(

编辑:好的,回应评论:关键字set绝不是与Visual Basic相关的遗产。 这是设置属性值的操作,vs get 检索操作的get 。 这与集合作为​​操作的想法无关。

想象一下,关键字实际上是fetchassign ,例如

 // 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 。 这个BCL团队博客文章有很多关于HashSet的详细信息,包括一个关于在名称中包含哈希的完全结论性讨论。 我怀疑BCL团队中的每个人都不喜欢使用名称HashSet

唯一的原因似乎是缺乏在.NET 3.5中实现这一点的资源。

.NET 4.0将包括ISet ,以及除HashSet – SortedSet之外的新实现。 查看提供的MSDN库链接 – 它们已经在.NET 4.0 beta1中提供。

set是一个C#语言关键字,自1.0版本开始就存在。 Is用于定义属性的值赋值部分( get用于实现属性的值读取部分)。 在这种情况下,你应该将’set’这个词理解为动词,就像设置一个值一样。

HashSet是Set的数学概念的特定实现。 它最初是在.NET 3.5中引入的。 BCL团队的这篇博客文章详细解释了其背后的原因,以及为什么名称为HashSet而不仅仅是Set一些线索: http : //blogs.msdn.com/bclteam/archive /2006/11/09/introducing-hashset-t-kim-hamilton.aspx 。

HashSet的情况下,您应该将’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
我想问题是你认为哪一组的基本行为?
是Add,Remove,Contains等。如果是这样,那么ICollection已经为它提供了一个接口。
如果它设置了诸如Union,Intersect等操作,那么你认为通用的东西足以抽象出合同风格的执行吗?

我不得不说我不知道​​这个问题的正确答案 – 我认为这是有争议的,我怀疑BCL团队最终会在未来的版本中推出这样的东西,但这取决于他们。 我个人并不认为这是一个巨大的缺失function

原帖

BCL根本没有Set系列,至少据我所知。
那里有一些第三方设置库,就像Iesi.Collections
HashSet是在.NET 3.5中引入的,用于创建快速集合集合,即您希望集合没有重复项。 它还具有典型的设置操作,例如Union和Join。 在HashSet上查看BCL团队的这个链接

您通常在之前必须使用List地方使用它,并在添加时检查重复项。
将项添加到HashSet也可以比List 快得多

更多细节:
HashSet的另一个不错的function是它不会抛出exception,如果你尝试添加一个副本它只是无法添加重复的条目,这节省了你必须在每个添加周围放置大量的try.catch块 – 好:)

我很确定BCL中没有Set类,至少在.NET 3.5中(不管是.NET 4.0)。 无论如何,你期望这样的课程需要什么?

HashSet本身只是一个普通的集合数据结构,它使用哈希码(对象的GetHashCode方法)来比较元素。 这只是实现集合类型的有效方式。 (检查相等性的其他方法可能会降低性能。)