我的理解是C#在某种意义上具有HashSet
和set
类型。我理解HashSet
是什么。但为什么set
是一个单独的词呢?为什么不是每一组都是HashSet<Object>
?
为什么C#没有通用Set
类型,类似于Dictionary
类型?从我的角度来看,我希望有一个具有标准查找/添加/删除性能的集合。我不关心它是用哈希还是别的来实现的。那么为什么不在这个版本的C#中创建一个实际上被实现为HashSet
的集合类,但在将来的版本中可能会有所不同?
或者为什么不至少接口ISet
?
感谢所有回答如下的人:ICollection
实现了您对ISet
的期望。但是,从我的观点来看,ICollection
实现IEnumerable
而集合不必是可枚举的---例如:1到2之间的实数集合(甚至更多,集合可以动态生成) )。我同意这是一个小咆哮,因为“普通程序员”很少需要不可数集。
好的,我想我明白了。 HashSet
绝对意味着被称为Set
但在某种意义上保留Set
这个词。更具体地说,.NET体系结构的创建者希望为不同的语言提供一致的集合(sic!)。这意味着标准类的每个名称都不得与.NET语言中的任何关键字一致。然而,单词Set
在VB.NET中使用,它实际上是不区分大小写的(是吗?),所以很遗憾没有空间进行操作。
神秘解决了:))
Alex Y.的新答案链接到MSDN page,它描述了即将推出的.NET 4.0界面 ISet
,其行为与我认为应该实现的相同并且已实现按HashedSet
。好结局。
答案 0 :(得分:19)
(关于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
部分。
有没有更明确的?
答案 1 :(得分:5)
没有设置<T>
。这个BCL team Blog post有很多关于HashSet的细节,包括一个关于在名称中包含hash的完全结论性的讨论。我怀疑BCL团队中的每个人都不喜欢使用名称HashSet <T>
的决定。
答案 2 :(得分:5)
这样做的唯一原因似乎是缺乏在.NET 3.5中实现这一点的资源。
除了ISet - HashSet之外,.NET 4.0还将包含SortedSet及其新实现。查看提供的MSDN库链接 - 它们已经在.NET 4.0 beta1中提供。
答案 3 :(得分:4)
set
是自1.0版以来一直存在的C#语言关键字。 Is用于定义属性的值赋值部分(get
用于实现属性的值读取部分)。在这种情况下,您应该将“set”一词理解为动词,如设置值。
HashSet<T>
是Set的数学概念的特殊实现。它最初是在.NET 3.5中引入的。 BCL小组发布的这篇博客文章详细介绍了其背后的原因,以及为什么名称为HashSet<T>
而不仅仅是Set<T>
的一些线索:http://blogs.msdn.com/bclteam/archive/2006/11/09/introducing-hashset-t-kim-hamilton.aspx。
在HashSet<T>
的情况下,您应该将'set'这个词理解为名词。
答案 4 :(得分:3)
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
答案 5 :(得分:2)
对,我现在明白你的问题了
不确定我是否100%能够看到ISet<T>
的需要
我想问题是你认为哪一组的基本行为?
是添加,删除,包含等等。如果是这样,那么ICollection<T>
已经为此提供了一个界面
如果它设置了诸如Union,Intersect等操作,那么你认为通用的东西足以抽象出合同风格的执行吗?
我不得不说我不知道这个问题的正确答案 - 我认为这是有争议的,我怀疑BCL团队最终可能会在未来版本中推出这样的东西,但这取决于他们。我个人并不认为这是一个巨大的缺失功能
BCL根本没有Set系列,至少不是我所知道的
那里有一些第三方设置库,如Iesi.Collections
在.NET 3.5中引入了HashSet<T>
来创建一个快速集合集合,即你想要一个没有重复的集合。它还具有典型的设置操作,例如Union和Join。
在HashSet上查看BCL团队的this link
您通常在之前必须使用List<T>
的地方使用它,并在添加时检查重复项。
将项目添加到HashSet<T>
也可以是significantly faster而不是列表
进一步的细节:
HashSet的另一个不错的功能是它不会抛出异常,如果你尝试添加一个副本它只是无法添加重复的条目,这样可以节省你必须在每个添加周围放置大量的try.catch块 - 很好:)
答案 6 :(得分:0)
我很确定BCL中没有Set<T>
类,至少在.NET 3.5中(不管是.NET 4.0)。无论如何,你期望这样的课程需要什么?
HashSet<T>
本身就是一个普通的集合数据结构,它使用哈希码(对象的GetHashCode
方法)来比较元素。这只是实现集合类型的有效方式。 (检查相等性的其他方法可能会降低性能。)