Set class with mathematical set equality by default [closed]

99封情书 提交于 2019-12-20 00:20:16

问题


HashSet does not use set equality semantics for the default equality operation.

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

This evaluates to false:

var c = a == b;

whereas in a mathematical sense, the two sets are equal. We can of course use SetEquals explicitly to compare using set equality:

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

If we create a set of these sets:

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

The result contains two elements. We'd need to pass a custom comparer to get set semantics for the parent set.

Here's a subclass of HashSet which implements set semantics by default.

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);
}

(This is based on one shown here.)

Example usage:

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

Is there a better approach?

Is there already a similar class available in a library somewhere?

来源:https://stackoverflow.com/questions/47688779/set-class-with-mathematical-set-equality-by-default

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!