Есть ли в .Net структура данных "Set"?

В идеале я ищу шаблонный логический класс Set. В нем будут все стандартные операции набора, такие как объединение, пересечение и т. Д., И свертывание дублированных элементов.

В итоге я создал свой собственный класс набора на основе C# Dictionary <> - просто используя Keys.

Ответов (6)

Вы проверили HashSet в 3.5?

HashSet<T> я думаю, это самое близкое из того, что вы получите.

Я не думаю, что в C# есть что-то встроенное, но я знаю, что в сети есть пара реализаций. Есть также несколько хороших статей на эту тему:

Это часть 6 из серии статей об эффективном представлении структуры данных. В этой части основное внимание уделяется представлению наборов в C#.

Реализация набора наборов
Реализация набора классов
Еще одна реализация набора классов

И наконец...

На самом деле я сам использовал эту библиотеку в качестве основы для реализации набора, которую я сделал год назад или около того.

Лучшая реализация набора, которую я когда-либо видел, является частью замечательной коллекции Wintellect Power Collections: http://www.codeplex.com/PowerCollections .

Реализацию набора можно найти здесь:
http://www.codeplex.com/PowerCollections/SourceControl/FileView.aspx?itemId=101886&changeSetId=6259
В нем есть все ожидаемые операции с наборами (объединение, пересечение и т. Д.).

Надеюсь это поможет!

Нет, во фреймворке его нет. Существует реализация с открытым исходным кодом, которую использует большинство проектов (например, nHibernate), под названием Iesi.Collections. Вот статья об этом CodeProject:

http://www.codeproject.com/KB/recipes/sets.aspx

Вот простая реализация:

public sealed class MathSet<T> : HashSet<T>, IEquatable<MathSet<T>>
{
    public override int GetHashCode() => this.Select(elt => elt.GetHashCode()).Sum().GetHashCode();

    public bool Equals(MathSet<T> obj) => SetEquals(obj);

    public override bool Equals(object obj) => Equals(obj as MathSet<T>);

    public static bool operator ==(MathSet<T> a, MathSet<T> b) =>
        ReferenceEquals(a, null) ? ReferenceEquals(b, null) : a.Equals(b);

    public static bool operator !=(MathSet<T> a, MathSet<T> b) => !(a == b);
}

Пример использования:

var a = new MathSet<int> { 1, 2, 3 };
var b = new MathSet<int> { 3, 2, 1 };

var c = a.Equals(b);                        // true

var d = new MathSet<MathSet<int>> { a, b }; // contains one element

var e = a == b;                             // true

См. Этот вопрос, чтобы узнать, почему этот подход был рассмотрен HashSet .