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

HashSetспользует семантику установленного равенства для операции равенства по умолчанию.

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

Это оцениваетfalse:

var c = a == b;

тогда как в математическом смысле два набора равны. Мы можем, конечно, использоватьSetEquals&nbsp;явно сравнить с использованием заданного равенства:

var d = a.SetEquals(b); // true

Если мы создадим набор этих наборов:

var e = new HashSet<HashSet<int>> { a, b };

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

Вот подклассHashSet&nbsp;который реализует заданную семантику по умолчанию.

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

Есть ли лучший подход?

Есть ли уже подобный класс в библиотеке?