26

老问题

我的理解是C#在某种意义上HashSetset类型。我明白是什么HashSet。但为什么set是一个单独的词?为什么不是每一套都是HashSet<Object>

新问题

为什么C#没有泛型Set类型,类似于Dictionary类型?从我的角度来看,我想要一个具有标准查找/添加/删除性能的集合。我不太关心它是用哈希还是其他东西实现的。那么为什么不创建一个在这个版本的 C# 中实际实现为 aHashSet但在未来版本中可能有所不同的集合类呢?

或者为什么不至少 interface ISet

回答

感谢以下回答的所有人:ICollection实现了很多您期望的ISet. 不过,从我的角度来看,虽然集合不一定是可枚举的——例如:1 到 2 之间的实数集(甚至可以动态生成集合)ICollectionIEnumerable我同意这是一个小小的抱怨,因为“普通程序员”很少需要不可数的集合。

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

谜团已揭开 :)

结语

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

4

7 回答 7

19

(您最初的问题set已得到解答。IIRC,“set”是英语中含义最不同的词......显然这对计算也有影响。)

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

公平地说,该ICollection<T>界面实际上涵盖了您想要的大部分内容ISet<T>,所以也许这不是必需的。但是,您可能会争辩说,集合的核心目的(主要是关于包含,并且只是与能够迭代元素无关)与集合并不完全相同。这很棘手。事实上,一个真正的数学集合可能是不可迭代或不可数的——例如,你可以拥有“1 到 2 之间的实数集合”。如果您有一个任意精度的数字类型,那么计数将是无限的,并且迭代它没有任何意义。

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

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

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

那是不是更清楚了?

于 2009-06-21T11:54:16.350 回答
6

造成这种情况的唯一原因似乎是缺乏在 .NET 3.5 中理想地实现这一点的资源。

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

于 2009-06-21T16:21:20.083 回答
5

没有 Set <T>。这篇BCL 团队博客文章有很多关于 HashSet 的详细信息,包括关于在名称中包含哈希的不完全决定性的讨论。我怀疑不是 BCL 团队中的每个人都喜欢使用名称 HashSet 的决定<T>

于 2009-06-21T11:38:52.310 回答
4

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

HashSet<T>是集合的数学概念的一种特殊实现。它最初是在 .NET 3.5 中引入的。BCL 团队的这篇博客文章解释了更多关于其背后的原因,以及为什么这个名字HashSet<T>不仅仅是这个名字的一些线索:http Set<T>: //blogs.msdn.com/bclteam/archive/2006/11/09/introducing -hashset-t-kim-hamilton.aspx

在这种情况下,HashSet<T>您应该将“集合”一词理解为名词。

于 2009-06-21T11:49:54.877 回答
3

Set 是 VB.NET 中的保留关键字(相当于 C# 中的 set)。VB.NET 可以使用与关键字同名的类/方法/等,但它们必须写在方括号之间,这很难看:

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
于 2009-06-21T12:44:26.640 回答
2

啊,对了,我现在明白你的问题了
。不确定我能否 100% 看到对ISet<T>.
我想问题是你认为哪个是集合的基本行为?
是添加、删除、包含等吗?如果是,那么ICollection<T>已经为此提供了一个接口。
如果它是诸如 Union、Intersect 等设置操作,那么您认为这是否足够通用以抽象出合同样式的执行?

我不得不说我不知道​​这个问题的正确答案——我认为这是有争议的,我怀疑 BCL 团队最终可能会在未来的版本中加入类似的东西,但这取决于他们。我个人不认为它是大量缺失的功能

原帖

BCL 根本没有 Set 集合,至少据我所知没有。
.NET 3.5 中引入了一些像Iesi.Collections
HashSet<T>这样的第 3 方集合库,用于创建快速集合集合,即您想要一个没有重复的集合。它还具有典型的集合操作,例如 Union 和 Join。在 HashSet 上查看BCL 团队的此链接

您通常会在以前必须使用的地方使用它,List<T>并在添加时检查重复项。
将项目添加到 aHashSet<T>也可以比 List快得多

一些进一步的细节:
HashSet 的另一个不错的功能是,如果您尝试添加重复项,它不会引发异常,它只是无法添加重复项,这使您不必在每个添加项周围放置大量 try.catch 块 - 很好:)

于 2009-06-21T11:41:09.777 回答
0

我很确定Set<T>BCL 中没有类,至少在 .NET 3.5 中(而且看起来也不是 .NET 4.0)。无论如何,您期望这样的课程需要什么?

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

于 2009-06-21T11:22:59.783 回答