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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1023697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:45:44  来源:igfitidea点击:

Why have HashSet but not Set in C#?

c#sethashset

提问by ilya n.

Old question

老问题

My understanding is that C# has in some sense HashSetand settypes. I understand what HashSetis. But why setis a separate word? Why not every set is HashSet<Object>?

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

New question

新问题

Why does C# has no generic Settype, similar to Dictionarytype? From my point of view, I would like to have a set with standard lookup/addition/deletion performance. I wouldn't care much whether it is realized with hashes or something else. So why not make a set class that would actually be implemented as a HashSetin this version of C# but perhaps somewhat different in a future version?

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

Or why not at least interface ISet?

或者为什么不是至少接口ISet

Answer

回答

Learned thanks to everyone who answered below: ICollectionimplements a lot of what you'd expect from ISet. From my point of view, though, ICollectionimplements IEnumerablewhile sets don't have to be enumerable --- example: set of real numbers between 1 and 2 (even more, sets can be generated dynamically). I agree this is a minor rant, as 'normal programmers' rarely need uncountable sets.

感谢在下面回答的每个人:ICollection实现了您对ISet. 不过,从我的角度来看,ICollection实现IEnumerablewhile 集合不必是可枚举的——例如:1 到 2 之间的实数集合(甚至更多,集合可以动态生成)。我同意这是一个小小的咆哮,因为“普通程序员”很少需要不可数的集合。

Ok, I think I get it. HashSetwas absolutely meant to be called Setbut the word Setis reserved in some sense. More specifically, creators of .NET architecture wanted to have a consistent set (sic!) of classes for different languages. This means that every name of the standard class must not coincide with any keyword in the .NET languages. The word Set, however, is used in VB.NET which is actually case-insensitive (is it?) so unfortunately there is no room for maneuvre there.

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

Mystery solved :)

谜团已揭开 :)

Epilogue

结语

The new answer by Alex Y. links to the MSDN pagewhich describes the upcoming .NET 4.0 interface ISetwhich behaves pretty much as I thought it should and is implemented by HashedSet. Happy end.

Alex Y. 的新答案链接到MSDN 页面,该页面描述了即将推出的 .NET 4.0 界面ISet,该界面的行为与我认为的非常相似,并且由HashedSet. 好结局。

采纳答案by Jon Skeet

(Your original question about sethas been answered. IIRC, "set" is the word with the most different meanings in the English language... obviously this has an impact in computing too.)

(你原来的问题set已经回答了。IIRC,“set”是英语中含义最不同的词……显然这对计算也有影响。)

I think it's fine to have HashSet<T>with that name, but I'd certainly welcome an ISet<T>interface. Given that HashSet<T>only arrived in .NET 3.5 (which in itself was surprising) I suspect we may eventually get a more complete collection of set-based types. In particular, the equivalent of Java's LinkedHashSet, which maintains insertion order, would be useful in some cases.

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

To be fair, the ICollection<T>interface actually covers most of what you'd want in ISet<T>, so maybe that isn't required. However, you could argue that the core purpose of a set (which is mostly about containment, and only tangentially about being able to iterate over the elements) isn't quite the same as a collection. It's tricky. In fact, a truly mathematical set may not be iterable or countable - for instance, you could have "the set of real numbers between 1 and 2." If you had an arbitrary-precision numeric type, the count would be infinite and iterating over it wouldn't make any sense.

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

Likewise the idea of "adding" to a set doesn't always make sense. Mutability is a tricky business when naming collections :(

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

EDIT: Okay, responding to the comment: the keyword setis in no way a legacy to do with Visual Basic. It's the operation which setsthe value of a property, vs getwhich retrievesthe operation. This has nothing to do with the idea of a set as an operation.

编辑:好的,回复评论:关键字set与 Visual Basic 无关。这是其操作设置一个属性,VS的值get,其检索操作。这与将集合作为操作的想法无关。

Imagine that instead the keywords were actually fetchand assign, e.g.

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

// Not real code!
public int Foo
{
    fetch
    {
        return fooField;
    } 
    assign
    {
        fooField = value;
    } 
}

Is the purpose clear there? Now the realequivalent of that in C# is just

那里的目的明确吗?现在在 C# 中真正的等价物只是

public int Foo
{
    get
    {
        return fooField;
    } 
    set
    {
        fooField = value;
    } 
}

So if you write:

所以如果你写:

x = y.Foo;

that will use the getpart of the property. If you write:

这将使用get财产的一部分。如果你写:

y.Foo = x;

that will use the setpart.

这将使用该set部分。

Is that any clearer?

有没有更清楚的?

回答by Noldorin

I'm pretty sure there's no Set<T>class in the BCL, at least in .NET 3.5 (and not .NET 4.0 either it seems). What would you expect is the need for such a class, anyway?

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

HashSet<T>is itself just an ordinary set data structure that uses hash codes (the GetHashCodemethod of an object) to compare elements. This is simply an efficient way of implementing a set type. (Other methods for checking equality would likely have lower performance.)

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

回答by ScottS

There is no Set<T>. This BCL team Blog posthas lot's of details on HashSet including a not entirely conclusive discussion on including hash in the name. I suspect not everyone on the BCL team liked the decision to use the name HashSet<T>.

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

回答by zebrabox

Ah right I understand your question now
Not sure I can 100% see the need for an ISet<T>.
I guess the question is which do you see as essential behaviour for a set?
Is it Add,Remove, Contains etc. If so then ICollection<T>already provides an interface for that.
If it's set operations such as Union, Intersect, etc then is that something you'd consider generic enough to abstract out to a contract style enforcement?

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

I have to say I don't know the right answer to this one - I think it's open to debate and I suspect the BCL team may end up putting something like this in a future version but that's up to them. I personally don't see it as massive missing piece of functionality

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

Original Post

原帖

The BCL doesn't have a Set collection at all, at least not as far as I know.
There a few 3rd party Set libs out there like Iesi.Collections
HashSet<T>was introduced in .NET 3.5 to create a fast set collection i.e where you want a collection with no duplicates. It also has typical set operations such as Union and Join. Check out this linkfrom BCL team on HashSet

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

You'd typically use it where previously you had to use List<T>and check for duplicates when adding.
Adding items to a HashSet<T>can also be significantly fasterthan List

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

Some further details:
Another nice feature of HashSet is that it doesn't throw an exception if you try and add a duplicate it just fails to add the duplicate entry which saves you having to put lots of try.catch blocks around every add - nice :)

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

回答by Mark Seemann

setis a C# language keyword that has been around since version 1.0. Is is used to define the value-assigning part of a property (and getis used to implement the value-reading part of a property). In this context you should understand the word 'set' as a verb, as in setting a value.

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

HashSet<T>is a particular implmentation of the mathematical concept of a Set. It was first introduced in .NET 3.5. This blog post by the BCL Team explains more about the reasoning behind it, as well as some clues to why the name is HashSet<T>and not just Set<T>: http://blogs.msdn.com/bclteam/archive/2006/11/09/introducing-hashset-t-kim-hamilton.aspx.

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

In the case of HashSet<T>you should understand the word 'set' as a noun.

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

回答by ggf31416

Set is a reserved keyword in VB.NET (it's the equivalent to set in C#). VB.NET can use classes/methods/etc with the same name as keywords but they have to be written between square brackets, which it's ugly:

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

回答by Alex Yakunin

The only reason for this seems lack of resources to implement this ideally in .NET 3.5.

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

.NET 4.0 will include ISet, as well as its new implementation in addition to HashSet- SortedSet. Check out the provided links to MSDN library - they're already available in .NET 4.0 beta1.

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