C# 字典使用的是自定义键,但键始终不相等

C# 字典使用的是自定义键,但键始终不相等,c#,dictionary,gethashcode,iequalitycomparer,containskey,C#,Dictionary,Gethashcode,Iequalitycomparer,Containskey,我正在使用RTBTextPointer作为字典中的自定义键 Init.SpintaxEditorPropertyMain.SpintaxListDict = new Dictionary<RTBTextPointer, SpintaxEditorProperties.SpintaxMappedValue>(new RTBTextPointerComparer()); everytime containsKey返回false,即使它包含,所以字典中会出现重复条目。。我的“Get

我正在使用RTBTextPointer作为字典中的自定义键

   Init.SpintaxEditorPropertyMain.SpintaxListDict = new Dictionary<RTBTextPointer, SpintaxEditorProperties.SpintaxMappedValue>(new RTBTextPointerComparer());
everytime containsKey返回false,即使它包含,所以字典中会出现重复条目。。我的“GetHashCode()中有什么错误吗?”

公共类RTBTextPointer
{
静态整数行;
静态int_列;
公共int行
{
得到
{
返回_行;
}
设置
{
_行=值;
}
}
公共int列
{
得到
{
返回_列;
}
设置
{
_列=值;
}
}
}
公共类RTBTextPointerComparer:IEqualityComparer
{
公共布尔等于(RTBTextPointer x,RTBTextPointer y)
{         
bool result=int.Equals(x.Column,y.Column)和&(int.Equals(x.Row,y.Row));
返回结果;
}
public int GetHashCode(RTBTextPointer obj)
{
var结果=0;
int hCode=obj.Column^obj.Row;
结果=hCode.GetHashCode();
返回结果;
}
}
请帮帮我
提前感谢

您的问题可能源于
RTBTextPointer
中的以下声明:

static int _row;
static int _column;
我想你不会这么做的。他们应该是

private int _row; 
private int _column; 
现在,这些变量引用
RTBTextPointer
static
成员。这意味着对它们的任何访问都将访问或变异它的
静态成员<代码>静态
成员可供类型的每个实例访问。如果您将它们设置为私有的,它们将适用于每个实例,我相信这是您的意图

一旦这一点得到纠正,我将重新考虑您的类的设计,至少如果您打算将其用作
词典中的键的话
RTBTextPointer
应该是不可变的,或者至少是
GetHashCode()
所依赖的字段和属性。原因如下:

当您将一个对象作为键添加到字典中时,它的关联值被放置在散列桶中,散列桶只是与散列代码关联的某个数据结构。假设我们有一些任意键
RTBTextPointer
,其中
Row=2
Column=2
的值为“Foo”。它的GetHashCode应该是0(2或2)

现在,调用
Dictionary.ContainsKey()
将返回true,查找
RTBTextPointer(2,2)
。现在考虑这个代码< RTBTextPointer > <代码>是否更改为<代码>行= 4 < /代码>。它的散列码现在应该是6(4或2)。对
Dictionary.ContainsKey()
的调用现在将为false,并且值
Foo
将不可访问,因为该键具有依赖于可变状态的哈希代码


作为最后的注释,我将考虑重写<代码>均衡器()/<代码>和<代码> GTHASCODE() <代码>对象< /代码>的方法。 我认为您不需要创建单独的比较器。只需重写

Equals
GetHashCode
就足够了

另外,如果您有这样的简单属性,您可以切换到

有关详细信息,请参阅

如果您有两个以上的属性,并且这些属性可以为null,则
GetHashCode
可能如下所示:

unchecked
{
    var result = 0;
    result = (result * 397) ^ (Prop1 != null ? Prop1.GetHashCode() : 0);
    result = (result * 397) ^ (Prop2 != null ? Prop2.GetHashCode() : 0);
    result = (result * 397) ^ (Prop3 != null ? Prop3.GetHashCode() : 0);
    result = (result * 397) ^ (Prop4 != null ? Prop4.GetHashCode() : 0);
    // ...
    return result;
}

你所说的“始终关键点不相等”到底是什么意思,即使它们是相等的?如果(Init.SpintaxEditorPropertyMain.SpintaxListDict.containskey(_index)==false){Init.SpintaxEditorPropertyMain.SpintaxListDict.Add(_index,_SpintaxMappedVal)}完全错过了
静态
,则Everyte time containskey返回false。接得好!
private int _row; 
private int _column; 
Hash Key                  Value
0    RTBTextPointer(2,2)  Foo
public class RTBTextPointer
{
    public int Row
    {
        get;
        set;
    }
    public int Column
    {
        get;
        set;
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }
        var other = obj as RTBTextPointer;
        if (other == null)
        {
            return false;
        }
        return other.Row == Row && other.Column == Column;
    }
    public override int GetHashCode()
    {
        unchecked
        {
            // 397 or some other prime number
            return (Row * 397) ^ Column;
        }
    }
}
unchecked
{
    var result = 0;
    result = (result * 397) ^ (Prop1 != null ? Prop1.GetHashCode() : 0);
    result = (result * 397) ^ (Prop2 != null ? Prop2.GetHashCode() : 0);
    result = (result * 397) ^ (Prop3 != null ? Prop3.GetHashCode() : 0);
    result = (result * 397) ^ (Prop4 != null ? Prop4.GetHashCode() : 0);
    // ...
    return result;
}