C# 字典使用的是自定义键,但键始终不相等
我正在使用RTBTextPointer作为字典中的自定义键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
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;
}