老问题

我的理解是 C# 在某种意义上 HashSetset 类型。我明白什么 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 哪个 检索 操作。这与集合作为​​运算的概念无关。

想象一下,关键词实际上是 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 <T>。这个 BCL团队博客文章有很多关于HashSet的详细信息,包括一个关于在名称中包含hash的完全结论性的讨论。我怀疑不是BCL团队中的每个人都喜欢使用名称HashSet <=>的决定。

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top