Почему имеют HashSet, но не Набор в C#?

Для работы в автономном / локальном режиме (предоставьте css с вашего сервера):

  1. npm install material-design-icons --save
  2. в src / styles.css add @import "~material-design-icons/iconfont/material-icons.css";
25
задан ilya n. 21 June 2009 в 17:03
поделиться

7 ответов

(На ваш первоначальный вопрос о set был дан ответ. IIRC, «set» - это слово с самыми разными значениями в английском языке ... очевидно, у него есть тоже влияет на вычисления.)

Я думаю, что HashSet с таким именем - это нормально, но я бы определенно приветствовал интерфейс ISet . Учитывая, что HashSet появился только в .NET 3.5 (что само по себе было удивительно), я подозреваю, что в конечном итоге мы можем получить более полную коллекцию типов, основанных на наборах. В частности, в некоторых случаях может быть полезен эквивалент Java LinkedHashSet , который поддерживает порядок вставки.

Честно говоря, интерфейс ICollection фактически покрывает большую часть что вы хотите в ISet < T> , так что, возможно, этого и не требуется. Однако вы можете возразить, что основная цель набора (которая в основном связана с сдерживанием и лишь косвенно - с возможностью итерации по элементам) не совсем то же самое, что и коллекция. Это сложно. Фактически, истинно математический набор не может быть итеративным или счетным - например, у вас может быть «набор действительных чисел от 1 до 2». Если бы у вас был числовой тип произвольной точности, счетчик был бы бесконечным, и повторение его не имело бы никакого смысла.

Точно так же идея «добавления» к множеству не всегда имеет смысл. При именовании коллекций изменяемость - непростая задача: (

РЕДАКТИРОВАТЬ: Хорошо, отвечая на комментарий: ключевое слово set никоим образом не является наследием Visual Basic. Это ' s операция, которая устанавливает значение свойства, 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;

, будет использоваться часть набора .

Это яснее?

Представьте, что вместо ключевых слов на самом деле были 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;

, будет использоваться часть набора .

Это яснее?

Представьте, что вместо ключевых слов на самом деле были 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;

, будет использоваться часть набора .

Это яснее?

19
ответ дан 28 November 2019 в 21:23
поделиться

Нет Set . Эта запись в блоге команды BCL содержит много деталей о HashSet, включая не совсем убедительное обсуждение включения хеша в имя. Я подозреваю, что не всем в команде BCL понравилось решение использовать имя HashSet .

5
ответ дан 28 November 2019 в 21:23
поделиться

set - это ключевое слово языка C #, которое существует с версии 1.0. Is используется для определения части свойства, присваивающей значение (а get используется для реализации части свойства, считывающей значение). В этом контексте вы должны понимать слово «набор» как глагол, например, при установке значения.

HashSet - это частное воплощение математической концепции набора. Впервые он был представлен в .NET 3.5. Это сообщение в блоге группы BCL объясняет больше о причинах этого, а также некоторые подсказки, почему это имя HashSet , а не просто Set : http://blogs.msdn.com/bclteam/archive/2006/11/09/introduction-hashset-t-kim-hamilton.aspx .

В случае HashSet

4
ответ дан 28 November 2019 в 21:23
поделиться

Единственной причиной этого кажется отсутствие ресурсов для идеальной реализации этого в .NET 3.5.

.NET 4.0 будет включать ISet , а также его новую реализацию в дополнение к HashSet - SortedSet . Ознакомьтесь с предоставленными ссылками на библиотеку MSDN - они уже доступны в .NET 4.0 beta1.

5
ответ дан 28 November 2019 в 21:23
поделиться

Set - это зарезервированное ключевое слово в VB.NET (эквивалентно set в C #). 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
3
ответ дан 28 November 2019 в 21:23
поделиться

Ага, теперь я понял ваш вопрос
Не уверен, что на 100% вижу необходимость в ISet .
Думаю, вопрос в том, какое поведение вы считаете важным для набора?
Это «Добавить», «Удалить», «Содержит» и т. Д. Если это так, то ICollection уже предоставляет интерфейс для этого.
Если это заданные операции, такие как Union, Intersect и т. Д., То можно ли считать это чем-то достаточно общим, чтобы абстрагироваться от применения стиля контракта?

Я должен сказать, что не знаю правильного ответа на этот вопрос - я думаю, что это открыто для обсуждения, и я подозреваю, что команда BCL может в конечном итоге добавить что-то подобное в будущую версию, но это их дело. Лично я не считаю это массовым отсутствием функциональности

Исходное сообщение

BCL вообще не имеет коллекции Set, по крайней мере, насколько мне известно.
Есть несколько сторонних наборов библиотек, например Iesi.Collections
HashSet был введен в .NET 3.5 для создания быстрой коллекции наборов, то есть там, где вам нужна коллекция без дубликатов. Он также имеет типичные операции с наборами, такие как Union и Join. Посмотрите эту ссылку от команды BCL на HashSet

. Обычно вы используете ее там, где раньше приходилось использовать List и проверять наличие дубликатов при добавлении.
Добавление элементов в HashSet также может быть значительно быстрее , чем List

Некоторые дополнительные сведения:
Еще одна приятная особенность HashSet заключается в том, что он не генерирует исключение, если вы пытаетесь добавить дубликат, он просто не может добавить дублирующую запись, что избавляет вас от необходимости помещать множество блоков try.catch вокруг каждого добавления - хорошо :)

2
ответ дан 28 November 2019 в 21:23
поделиться

Я почти уверен, что в BCL нет класса Set , по крайней мере, в .NET 3.5 (и не в .NET 4.0, похоже). В любом случае, чего вы ожидаете от такого класса?

HashSet - это просто обычная структура данных набора, которая использует хэш-коды (метод GetHashCode объекта) для сравнения элементов. Это просто эффективный способ реализации заданного типа. (Другие методы проверки равенства, вероятно, будут иметь более низкую производительность.)

0
ответ дан 28 November 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: