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

时间:2009-06-21 11:21:18

标签: c# set hashset

旧问题

我的理解是C#在某种意义上具有HashSetset类型。我理解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。好结局。

7 个答案:

答案 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 检索操作。这与集合作为​​操作的想法无关。

想象一下,关键字实际上是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部分。

有没有更明确的?

答案 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方法)来比较元素。这只是实现集合类型的有效方式。 (检查相等性的其他方法可能会降低性能。)