Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.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
C# 未找到检索到的字典键_C#_Dictionary_Readonly Collection - Fatal编程技术网

C# 未找到检索到的字典键

C# 未找到检索到的字典键,c#,dictionary,readonly-collection,C#,Dictionary,Readonly Collection,我有一个SortedDictionary声明如下: SortedDictionary<MyObject,IMyInterface> dict = new SortedDictionary<MyObject,IMyInterface>(); 当我使用调试器将鼠标悬停在字典上(错误发生后),我可以清楚地看到我试图引用的同一个键实际上包含在字典中。我正在使用MyObjects的ReadOnlyCollection填充字典。也许那里发生了一些奇怪的事情?我试图重写=操作符和Eq

我有一个
SortedDictionary
声明如下:

SortedDictionary<MyObject,IMyInterface> dict = new SortedDictionary<MyObject,IMyInterface>();
当我使用调试器将鼠标悬停在字典上(错误发生后),我可以清楚地看到我试图引用的同一个键实际上包含在字典中。我正在使用
MyObjects
ReadOnlyCollection
填充字典。也许那里发生了一些奇怪的事情?我试图重写
=
操作符和
Equals
方法来获得我想要的显式比较,但没有这样的运气。这真的不重要,因为我实际上是直接从
字典
获取一个键,然后使用同一个键查询
字典
。我不知道是什么原因造成的。有人见过这种行为吗

编辑1

在重写
Equals
的过程中,我也重载了(正如MS建议的那样)
GetHashCode
。下面是为感兴趣的人提供的
MyObject
的实现:

public class MyObject
{
public string UserName { get; set;}
public UInt64 UserID  { get; set;}

    public override bool Equals(object obj)
    {
        if (obj == null || GetType()!= obj.GetType())
        {
            return false;
        }

        // Return true if the fields match:
        return this.Equals((MyObject)obj);
    }

    public bool Equals(MyObject other)
    {
        // Return true if the fields match
        return this.UserID == other.UserID;
    }

    public override int GetHashCode()
    {
        return (int)this.UserID;
    }


public static bool operator ==( MyObject a, MyObject b)
{
    // If both are null, or both are same instance, return true.
    if (System.Object.ReferenceEquals(a, b))
    {
        return true;
    }

    // If one is null, but not both, return false.
    if (((object)a == null) || ((object)b == null))
    {
        return false;
    }

    // Return true if the fields match:
    return a.UserID == b.UserID
}

public static bool operator !=( MyObject a, MyObject b)
{
    return !(a == b);
}
}
我从调试中注意到,如果我为表达式添加一个快速监视(在抛出
KeyNotFoundException
之后):

dict.ElementAt(0).Key == value;
这是真的。这怎么可能

编辑2 因此,问题最终是因为
SortedDictionary
(以及
Dictionary
)不是线程安全的。有一个后台线程正在字典上执行一些操作,这些操作似乎触发了集合的调用(向集合中添加项可以做到这一点)。同时,当字典遍历这些值以查找我的键时,集合正在被更改,即使它在那里也找不到我的键


很抱歉你们所有人都要求在这一个代码,我目前正在调试我继承的应用程序,我没有意识到这是在一个定时的后台线程上进行的。因此,我认为我复制并粘贴了所有相关的代码,但我没有意识到在所有操作集合的东西后面都运行着另一个线程。

除了重载
==
等于
之外,请确保使用合适的哈希函数覆盖。具体请参见文档中的本规范:

  • 如果两个对象比较相等,则每个对象的
    GetHashCode
    方法必须返回相同的值。但是,如果两个对象没有 比较为相等,两个对象的
    GetHashCode
    方法不相同 必须返回不同的值
  • 对象的
    GetHashCode
    方法必须始终返回相同的哈希代码,只要不修改对象状态 它确定对象的Equals方法的返回值。注 这仅适用于应用程序的当前执行, 如果应用程序被激活,则可以返回不同的哈希代码 再跑一次
  • 为了获得最佳性能,哈希函数应该为所有输入生成均匀分布,包括高度聚集的输入。 这意味着对对象状态的小修改应该 导致对生成的哈希代码进行大量修改以获得最佳哈希 表性能
  • 哈希函数的计算成本应该很低
  • GetHashCode
    方法不应引发异常

我同意您在将
UserID
属性添加为密钥后无意中对其进行了修改。但是,由于在
MyObject
中测试平等性的唯一重要属性是
UserID
(因此这是
字典
关心的唯一属性),我建议重构代码,使用简单的
字典

Dictionary<ulong, IMyInterface> dict = new Dictionary<string, IMyInterface>();
ulong userID = dict.Keys.First();
var value = dict[userID];
Dictionary dict=new Dictionary();
ulong userID=dict.Keys.First();
var值=dict[userID];

除了重载
=
等于
之外,请确保使用合适的哈希函数重写。具体请参见文档中的本规范:

  • 如果两个对象比较相等,则每个对象的
    GetHashCode
    方法必须返回相同的值。但是,如果两个对象没有 比较为相等,两个对象的
    GetHashCode
    方法不相同 必须返回不同的值
  • 对象的
    GetHashCode
    方法必须始终返回相同的哈希代码,只要不修改对象状态 它确定对象的Equals方法的返回值。注 这仅适用于应用程序的当前执行, 如果应用程序被激活,则可以返回不同的哈希代码 再跑一次
  • 为了获得最佳性能,哈希函数应该为所有输入生成均匀分布,包括高度聚集的输入。 这意味着对对象状态的小修改应该 导致对生成的哈希代码进行大量修改以获得最佳哈希 表性能
  • 哈希函数的计算成本应该很低
  • GetHashCode
    方法不应引发异常

我同意您在将
UserID
属性添加为密钥后无意中对其进行了修改。但是,由于在
MyObject
中测试平等性的唯一重要属性是
UserID
(因此这是
字典
关心的唯一属性),我建议重构代码,使用简单的
字典

Dictionary<ulong, IMyInterface> dict = new Dictionary<string, IMyInterface>();
ulong userID = dict.Keys.First();
var value = dict[userID];
Dictionary dict=new Dictionary();
ulong userID=dict.Keys.First();
var值=dict[userID];

我有一个怀疑-可能是您在插入密钥后更改了该密钥的
用户ID
。例如,这将说明问题:

var key = new MyObject { UserId = 10 };
var dictionary = new Dictionary<MyObject, string>();
dictionary[key] = "foo";

key.UserId = 20; // This will change the hash code

var value = dict[key]; // Bang!
var key=newmyobject{UserId=10};
var dictionary=newdictionary();
字典