Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net someDictionary.ContainsKey(someDictionary.Keys.First)。。。这是假的吗?_.net_Vb.net - Fatal编程技术网

.net someDictionary.ContainsKey(someDictionary.Keys.First)。。。这是假的吗?

.net someDictionary.ContainsKey(someDictionary.Keys.First)。。。这是假的吗?,.net,vb.net,.net,Vb.net,这是VB.NET 有人知道是什么导致标题中提到的表达式返回False吗 我确信的事情: 字典里有钥匙 相等比较器为每个键返回一个不同的hashcode,并且该hashcode对于相同的输入总是相同的 将someDictionary.Keys.First与新构造的等价于该键的对象进行比较将返回True someDictionary.Comparer.Equals(someDictionary.Keys.First,与FirstKey等价的新对象)返回True 虽然someDictionary.Ke

这是VB.NET

有人知道是什么导致标题中提到的表达式返回False吗

我确信的事情:

  • 字典里有钥匙
  • 相等比较器为每个键返回一个不同的hashcode,并且该hashcode对于相同的输入总是相同的
  • 将someDictionary.Keys.First与新构造的等价于该键的对象进行比较将返回True
  • someDictionary.Comparer.Equals(someDictionary.Keys.First,与FirstKey等价的新对象)返回True
  • 虽然someDictionary.Keys.First.GetHashCode始终返回相同的值(即使在多个程序执行中),但对重复创建的等效对象调用GetHashCode不会返回相同的值。所讨论的对象本质上只是一个布尔值的4元组,哈希代码是新的位数组(新的布尔值{}(obj.First,obj.Second,obj.Third,obj.Fourth})
  • 更新:只有一个线程

  • 更新:显然,该哈希代码实现并不总是返回相同的值。我将尝试诊断这是否是问题所在。

    竞争条件如何


    由于时间键。首先被检索,另一个线程更改字典,然后对没有该键的字典进行求值?

    因此,将哈希代码更改为布尔值字符串值串联的哈希代码修复了问题


    奇怪的是,当我运行程序时,哈希代码总是相同的,但是如果我使用调试器中的即时窗口来查询哈希代码,它总是不同的。

    执行
    dict.ContainsKey(dict.Keys.First)如果
    键的哈希代码。First
    在放入哈希表后已更改,则
    不会返回true

    原因是这两种方法使用单独的查找。
    dict.Keys.First
    不依赖于散列码,可能只是指向任意“散列桶”的指针,该项恰好位于其顶部

    dict.ContainsKey()
    ,但是,使用哈希代码选择要查找的存储桶。如果
    dict.Keys.First
    的哈希代码自添加以来已更改,则它可能属于不同的哈希存储桶,但这不会反映或更新在哈希表中;对象在字典中“丢失”

    (在C#中,但可翻译为VB.NET,且未经测试)

    类Foo{ 公共国际一级; 公共覆盖int GetHashCode(){ 返回i.GetHashCode(); } } var dictionary=newdictionary(); var foo=new foo{i=1;} 加上(foo,“我错了”); foo.i=2; if(dictionary.ContainsKey(dictionary.Keys.First)){ System.Console.WriteLine(dictionary[dictionary.Keys.First]); }否则{ System.Console.WriteLine(“我是对的”); }
    您可以做的是先在comparer中调试,然后在字典中,您可以手动将断点添加到ContainsKey()并查看发生了什么。(您可能已经知道这一点,但在VS中,您可以执行断点、新建、在函数处中断,然后手动写入函数的全名;这是一个非常有用的功能。)嗯,在我的情况下,什么都没有改变…很明显,有些东西是改变了,但它不在我的代码中。它在BitArray中。无论如何,谢谢你提供的信息。这对参考很有用。 class Foo { public int i; public override int GetHashCode() { return i.GetHashCode(); } } var dictionary = new Dictionary<Foo,string> (); var foo = new Foo { i = 1; } dictionary.Add (foo, "I was wrong."); foo.i = 2; if (dictionary.ContainsKey (dictionary.Keys.First)) { System.Console.WriteLine (dictionary[dictionary.Keys.First]); } else { System.Console.WriteLine ("I was right."); }