使用自定义键定义哈希集

时间:2014-03-09 19:41:25

标签: c# key hashset

我需要定义hashset哪个键是MyClass

public class MyClass
{
    private string m_x;
    private string m_y;
    MyClass(string x,string y)
    {
       m_x = x;
       m_y =y;
    }
}

所以我有

HashSet <MyClass> myHash;
MyClass m = new MyClass("1","123");
myHash.Add(m);
bool isContained = myHash.Contains(m);

IsContainedfalse ....出了什么问题? 什么可能是另一个容器,它允许保存唯一键?如果密钥在内部且复杂度最低,则返回答案?

2 个答案:

答案 0 :(得分:2)

a)假设您不想通过引用比较对象,则应覆盖GetHashCodeEquals方法{ {1}}

MyClass

HashSet<MyClass> myHash = new HashSet<MyClass>();
MyClass m1 = new MyClass("1", "123");
MyClass m2 = new MyClass("1", "123");
myHash.Add(m1);
bool b = myHash.Contains(m2); //true

b)您还可以使用IEqualityComparer来比较您的对象,但在这种情况下,您需要一些公共属性

public class MyClass
{
    private string m_x;
    private string m_y;
    public MyClass(string x, string y)
    {
        m_x = x;
        m_y = y;
    }

    public override int GetHashCode()
    {
        return m_x.GetHashCode() ^ m_y.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj)) return true;
        if (obj == null) return false;
        var other = obj as MyClass;
        return m_x == other.m_x && m_y == other.m_y;
    }
}

现在,您只需要将比较器提供给HashSet的构造函数

public class MyClass
{
    public string m_x;
    public string m_y;
    public MyClass(string x, string y)
    {
        m_x = x;
        m_y = y;
    }
}

public class MyEqualityComparer : IEqualityComparer<MyClass>
{

    public bool Equals(MyClass x, MyClass y)
    {
        return x.m_x == y.m_x && x.m_y == y.m_y;
    }

    public int GetHashCode(MyClass obj)
    {
        return obj.m_x.GetHashCode() ^ obj.m_y.GetHashCode();
    }
}

答案 1 :(得分:1)

只需更改MyClass,即可实现Equals和GetHashCode:

public class MyClass
{
    private string m_x;
    private string m_y;

    public MyClass(string x, string y)
    {
        m_x = x;
        m_y = y;
    }

    public override bool Equals(object obj)
    {
        var typed = obj as MyClass;
        if (typed == null) return false;
        return typed.m_x == m_x && typed.m_y ==m_y;
    }

    public override int GetHashCode()
    {
        return new {m_x, m_y}.GetHashCode();
    }
}

现在IsContained2也是如此,即使它尚未添加到HashSet中:

HashSet<MyClass> myHash =new HashSet<MyClass>();
MyClass m = new MyClass("1", "123");
MyClass m2 = new MyClass("1", "123");
myHash.Add(m);
bool isContained = myHash.Contains(m);
bool isContained2 = myHash.Contains(m2); // True!