C# 使用自定义密钥定义哈希集

C# 使用自定义密钥定义哈希集,c#,key,hashset,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"); myHa

我需要定义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);
HashSet-myHash;
MyClass m=新的MyClass(“1”、“123”);
myHash.Add(m);
bool isContained=myHash.Contains(m);
IsContained
false
…怎么了? 另一个允许保存唯一密钥的容器是什么?如果密钥在内部且复杂度最低,则返回答案?

a)假设您不想通过引用来比较对象,则应重写
GetHashCode
Equals
方法的
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
{
    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();
    }
}
公共类MyClass
{
公共字符串m_x;
公共字符串m_y;
公共MyClass(字符串x、字符串y)
{
m_x=x;
m_y=y;
}
}
公共类MyQualityComparer:IEqualityComparer
{
公共布尔等于(MyClass x,MyClass y)
{
返回x.m_x==y.m_x&&x.m_y==y.m_y;
}
公共int GetHashCode(MyClass obj)
{
返回obj.m_x.GetHashCode()^obj.m_y.GetHashCode();
}
}
现在,您只需要将比较器提供给HashSet的构造函数

HashSet<MyClass> myHash = new HashSet<MyClass>( new MyEqualityComparer());
HashSet myHash=newhashset(new MyEqualityComparer());
a)假设您不想通过引用来比较对象,您应该重写
GetHashCode
Equals
方法的
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
{
    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();
    }
}
公共类MyClass
{
公共字符串m_x;
公共字符串m_y;
公共MyClass(字符串x、字符串y)
{
m_x=x;
m_y=y;
}
}
公共类MyQualityComparer:IEqualityComparer
{
公共布尔等于(MyClass x,MyClass y)
{
返回x.m_x==y.m_x&&x.m_y==y.m_y;
}
公共int GetHashCode(MyClass obj)
{
返回obj.m_x.GetHashCode()^obj.m_y.GetHashCode();
}
}
现在,您只需要将比较器提供给HashSet的构造函数

HashSet<MyClass> myHash = new HashSet<MyClass>( new MyEqualityComparer());
HashSet myHash=newhashset(new MyEqualityComparer());
a)假设您不想通过引用来比较对象,您应该重写
GetHashCode
Equals
方法的
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
{
    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();
    }
}
公共类MyClass
{
公共字符串m_x;
公共字符串m_y;
公共MyClass(字符串x、字符串y)
{
m_x=x;
m_y=y;
}
}
公共类MyQualityComparer:IEqualityComparer
{
公共布尔等于(MyClass x,MyClass y)
{
返回x.m_x==y.m_x&&x.m_y==y.m_y;
}
公共int GetHashCode(MyClass obj)
{
返回obj.m_x.GetHashCode()^obj.m_y.GetHashCode();
}
}
现在,您只需要将比较器提供给HashSet的构造函数

HashSet<MyClass> myHash = new HashSet<MyClass>( new MyEqualityComparer());
HashSet myHash=newhashset(new MyEqualityComparer());
a)假设您不想通过引用来比较对象,您应该重写
GetHashCode
Equals
方法的
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
{
    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();
    }
}
公共类MyClass
{
公共字符串m_x;
公共字符串m_y;
公共MyClass(字符串x、字符串y)
{
m_x=x;
m_y=y;
}
}
公共类MyQualityComparer:IEqualityComparer
{
公共布尔等于(MyClass x,MyClass y)
{
返回x.m_x==y.m_x&&x.m_y==y.m_y;
}
公共int GetHashCode(MyClass obj)
{
返回obj.m_x.GetHashCode()^obj.m_y.GetHashCode();
}
}
现在,您只需要将比较器提供给HashSet的构造函数

HashSet<MyClass> myHash = new HashSet<MyClass>( new MyEqualityComparer());
HashSet myHash=newhashset(new MyEqualityComparer());

只需更改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<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!
HashSet myHash=newhashset();
MyClass m=新的MyClass(“1”、“123”);
MyClass m2=新MyClass(“1”、“123”);
myHash.Add(m);
bool isContained=myHash.Contains(m);
bool isContained2=myHash.Contains(m2);//真的!

只需更改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<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!
HashSet myHash=newhashset();
MyClass m=新的MyClass(“1”、“123”);
MyClass m2=新MyClass(“1”、“123”);
myHash.Add(m);
bool isContained=myHash.Contains(m);
bool isContained2=myHash.Contains(m2);//真的!

只需更改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<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!
HashSet myHash=newhashset();
MyClass m=新的MyClass(“1”、“123”);
MyClass m2=新MyClass(“1”、“123”);
myHash.Add(m);
bool isContained=myHash.Contains(m);
bool isContained2=myHash.Contains(m2);//真的!

只需更改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<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!
HashSet myHash=newhashset();
MyClass m=新的MyClass(“1”、“123”);
MyClass m2=新MyClass(“1”、“123”);
myHash.Add(m);
bool isContained=myHash.Contains(m);
bool isContained2=myHash.Contains(m2);//真的!

您能显示实际代码吗?这应该会抛出一个NRE.Override GetHashCode,EqualsCan无法复制,对我来说很好。你能发布一个复制行为的代码吗帮助?您能显示实际代码吗?这将抛出一个NRE.Override GetHashCode和EqualsCan-not-reproduction,w