默认情况下使用数学集合相等设置类

dha*_*ech 5 c# hashset

HashSet 不对默认相等操作使用设置相等语义。

var a = new HashSet<int> { 1, 2, 3 };
var b = new HashSet<int> { 3, 2, 1 };
Run Code Online (Sandbox Code Playgroud)

这评估为false

var c = a == b;
Run Code Online (Sandbox Code Playgroud)

而在数学意义上,这两个集合是相等的。我们当然可以使用SetEquals显式来使用集合相等进行比较:

var d = a.SetEquals(b); // true
Run Code Online (Sandbox Code Playgroud)

如果我们创建一组这些集合:

var e = new HashSet<HashSet<int>> { a, b };
Run Code Online (Sandbox Code Playgroud)

结果包含两个元素。我们需要传递一个自定义比较器来获取父集的集语义。

这是HashSet默认情况下实现集合语义的子类。

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);
}
Run Code Online (Sandbox Code Playgroud)

(这是基于此处显示的一个。)

用法示例:

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
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法?

某个地方的图书馆中是否已经有类似的课程?