如何使用HashSet <MyCustomClass>删除MyCustomClass的重复项?

Zol*_*mon 4 c# c#-3.0

我有一个HashSet<MyCustomClass> mySet = new HashSet<MyCustomClass>();,我希望删除包含相同值的所有MyCustomClass.

假设MyCustomClass看起来像这样:

public class MyCustomClass
{
    Point point;

    public MyCustomClass(int x, int y)
    {
        point.X = x;
        point.Y = y;
    }

    // Other methods...
}
Run Code Online (Sandbox Code Playgroud)

我尝试IEqualityComparer像MSDN建议的那样实现,并通过它的构造函数传递它,HashSet<MyCustomClass>();但我最终失败了.

什么是正确的方法?

编辑:

这是我的Chain班级和我的ChainEqualityComparer:

public class Chain
{
    HashSet<Mark> chain;
    HashSet<Mark> marks;

    public Chain(HashSet<Mark> marks)
    {
        chain = new HashSet<Mark>();
        this.marks = marks;
    }       
    // Other methods...
}

public class ChainEqualityComparer : IEqualityComparer<Chain>
{
    #region IEqualityComparer<Chain> Members

    public bool Equals(Chain x, Chain y)
    {
        if (x.ChainWithMarks.Count == y.ChainWithMarks.Count)
        {
            foreach (Mark mark in x.ChainWithMarks)
            {
                if (!y.ChainWithMarks.Contains(mark))
                    return false;
            }
            return true;
        }

        return false;
    }

    public int GetHashCode(Chain obj)
    {
        return obj.GetHashCode() ^ obj.GetType().GetHashCode();
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

这是我的Mark班级:

  public class Mark
{
    int x;
    int y;

    public Mark(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return y; }
        set { y = value; }
    }
}

public class MarkEqualityComparer : IEqualityComparer<Mark>
{
    #region IEqualityComparer<Mark> Members

    public bool Equals(Mark x, Mark y)
    {
        return (x.X == y.X) && (x.Y == y.Y);
    }

    public int GetHashCode(Mark obj)
    {
        return obj.GetHashCode() ^ obj.GetType().GetHashCode();
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

(如果代码太多,我可以将代码粘贴到代码中......)

Dre*_*kes 5

您可以使用EqualityComparer或仅覆盖Equals和GetHashCode.

您必须确保任何您认为是重复的内容都被标识为具有等效的哈希代码,并在测试相等时返回true.

我的猜测是你没有返回相同的哈希码.你可以发布相等比较器的代码吗?

作为测试,您可以:

var set = new HashSet<MyCustomClass>();
var a = new MyCustomClass(1,2);
var b = new MyCustomClass(1,2);
set.Add(a);
set.Add(b);
Assert.IsTrue(a.Equals(b));
Assert.IsTrue(b.Equals(a));
Assert.AreEqual(a.GetHashCode(), b.GetHashCode());
Assert.AreEqual(1, set.Count);
Run Code Online (Sandbox Code Playgroud)

一组类似的测试也适用于相等比较器.

编辑

是的,怀疑它是哈希码功能.您需要根据类型本身的值来计算它.一个常见的错误.

public int GetHashCode(Mark obj)
{
    return ((MyCustomClass)obj).point.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

假设point是您类型中唯一的状态字段.