Почему HashSet, но не установлен в C #?
Вопрос
Старый вопрос
Насколько я понимаю, C # в некотором смысле имеет типы HashSet
и set
. Я понимаю, что HashSet<Object>
Но почему Set
это отдельное слово? Почему не каждый набор Dictionary
?
Новый вопрос
Почему в C # нет общего ISet
типа, похожего на ICollection
тип? С моей точки зрения, я хотел бы иметь набор со стандартной производительностью поиска / добавления / удаления. Мне было бы все равно, реализовано ли это с помощью хэшей или как-то еще Так почему бы не создать класс набора, который на самом деле был бы реализован как IEnumerable
в этой версии C #, но, возможно, несколько отличался бы в будущей версии?
Или почему бы не по крайней мере интерфейс HashedSet
?
Ответ
Спасибо всем, кто ответил ниже: <=> реализует многое из того, что вы ожидаете от <=>. Однако, с моей точки зрения, <=> реализует <=>, в то время как наборы не должны быть перечисляемыми --- пример: набор действительных чисел от 1 до 2 (даже больше, наборы могут генерироваться динамически). Я согласен, что это небольшая разглагольствование, поскольку «нормальным программистам» редко нужны бесчисленные наборы.
Хорошо, я думаю, что понял. <=> было определенно предназначено, чтобы называться <=>, но слово <=> зарезервировано в некотором смысле. В частности, создатели архитектуры .NET хотели иметь согласованный набор (sic!) Классов для разных языков. Это означает, что каждое имя стандартного класса не должно совпадать ни с одним ключевым словом в языках .NET. Слово <=>, однако, используется в VB.NET, который фактически не учитывает регистр (не так ли?), Поэтому, к сожалению, там нет места для маневра.
Тайна раскрыта:)
Эпилог
Новый ответ Алекса Я. ссылается на Страница MSDN , которая описывает предстоящий интерфейс .NET 4.0 <=> , который ведет себя так, как я думал, и должен быть реализован <=>. Счастливый конец. Р>
Решение
(На ваш первоначальный вопрос о set
был дан ответ. IIRC, " set " это слово с самыми разными значениями в английском языке ... очевидно, это влияет на вычисления тоже.)
Я думаю, что хорошо иметь HashSet<T>
с таким именем, но я бы, конечно, приветствовал интерфейс ISet<T>
. Учитывая, что LinkedHashSet
появился только в .NET 3.5 (что само по себе было удивительно), я подозреваю, что в конечном итоге мы можем получить более полную коллекцию типов на основе множеств. В частности, эквивалент Java ICollection<T>
, который поддерживает порядок вставки, был бы полезен в некоторых случаях.
Честно говоря, интерфейс get
покрывает большую часть того, что вы хотите в fetch
, так что, возможно, это не требуется. Тем не менее, вы можете утверждать, что основная цель набора (который главным образом связан с защитой и только косвенно заключается в возможности перебирать элементы) не совсем совпадает с коллекцией. Это сложно. На самом деле, действительно математический набор не может быть итеративным или счетным - например, у вас может быть & Quot; набор действительных чисел от 1 до 2. & Quot; Если бы у вас был числовой тип с произвольной точностью, счетчик был бы бесконечным, и повторение по нему не имело бы никакого смысла.
Аналогично идее & добавления " к набору не всегда имеет смысл. Изменчивость - сложная задача при именовании коллекций: (
РЕДАКТИРОВАТЬ: Хорошо, отвечая на комментарий: ключевое слово assign
никоим образом не является наследием Visual Basic. Это операция, которая устанавливает значение свойства, а не <=>, которая возвращает операцию. Это не имеет ничего общего с идеей множества как операции.
Представьте себе, что вместо этого ключевые слова на самом деле были <=> и <=>, например
.// 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;
, которая будет использовать <=> часть свойства. Если вы напишите:
y.Foo = x;
который будет использовать <=> часть.
Это понятнее?
Другие советы
set
- это ключевое слово языка C #, существующее с версии 1.0. Is используется для определения присваивающей значение части свойства (а get
используется для реализации считывающей значение части свойства). В этом контексте вы должны понимать слово «набор» как глагол, как при установке значения.
HashSet<T>
является конкретным воплощением математической концепции множества. Впервые он был представлен в .NET 3.5. Это сообщение в блоге команды BCL объясняет более подробно причины этого, а также некоторые подсказки, почему имя Set<T>
, а не просто <=>: http://blogs.msdn.com/bclteam/archive/2006/11/09/introduction -hashset-трет-ким-hamilton.aspx . р>
В случае <=> вы должны понимать слово «набор» как существительное.
Set - это зарезервированное ключевое слово в VB.NET (это эквивалент для набора в 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
Хорошо, теперь я понимаю ваш вопрос
Не уверен, что смогу на 100% увидеть необходимость в ISet<T>
.
Я думаю, вопрос в том, что вы считаете важным поведением для набора?
Добавить, удалить, содержит и т. Д. Если да, то ICollection<T>
уже предоставляет интерфейс для этого.
Если это такие операции над множествами, как Union, Intersect и т. Д., Тогда это то, что вы считаете достаточно универсальным, чтобы абстрагироваться от применения стиля контракта? Р>
Я должен сказать, что не знаю правильного ответа на этот вопрос - я думаю, что он открыт для дебатов, и я подозреваю, что команда BCL может в конечном итоге выложить что-то подобное в будущей версии, но это зависит от них. Лично я не вижу в этом значительного недостатка функциональности
Исходное сообщение
BCL вообще не имеет коллекции Set, по крайней мере, насколько я знаю.
Есть несколько сторонних библиотек, таких как Iesi.Collections
HashSet<T>
была введена в .NET 3.5 для создания коллекции быстрых наборов, т.е. там, где вы хотите коллекцию без дубликатов. Он также имеет типичные операции над множествами, такие как объединение и соединение.
Проверьте эту ссылку от команды BCL на HashSet
Обычно вы используете его там, где ранее вам приходилось использовать List<T>
, и проверяете наличие дубликатов при добавлении.
Добавление элементов в <=> также может быть значительно быстрее , чем список
Дополнительная информация:
Еще одна приятная особенность HashSet состоит в том, что он не выдает исключение, если вы пытаетесь добавить дубликат, просто не удается добавить дублирующую запись, что избавляет вас от необходимости помещать множество блоков try.catch вокруг каждого добавления - nice:) р>
Я почти уверен, что в BCL нет класса Set<T>
, по крайней мере, в .NET 3.5 (и, кажется, не .NET 4.0). Во всяком случае, чего бы вы ожидали от такого класса?
HashSet<T>
сама по себе представляет собой обычную структуру данных набора, которая использует хеш-коды (метод GetHashCode
объекта) для сравнения элементов. Это просто эффективный способ реализации набора типа. (Другие методы проверки равенства, вероятно, будут иметь более низкую производительность.)