Definir classe com igualdade matemática definida por padrão [fechado]
HashSet
não usa a semântica de igualdade de conjunto para a operação de igualdade padrão.
var a = new HashSet<int> { 1, 2, 3 };
var b = new HashSet<int> { 3, 2, 1 };
Isso avalia comofalse
:
var c = a == b;
enquanto, no sentido matemático, os dois conjuntos são iguais. Claro que podemos usarSetEquals
explicitamente para comparar usando igualdade de conjunto:
var d = a.SetEquals(b); // true
Se criarmos um conjunto desses conjuntos:
var e = new HashSet<HashSet<int>> { a, b };
O resultado contém dois elementos. Precisávamos passar um comparador personalizado para definir a semântica do conjunto pai.
Aqui está uma subclasse deHashSet
que implementa a semântica definida por padrão.
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);
}
(Isso se baseia em um exemploaqui.)
Exemplo de uso:
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
Existe uma abordagem melhor?
Já existe uma classe semelhante disponível em uma biblioteca em algum lugar?