尽管键存在,但字典抛出KeyNotFoundException异常

3

我有一个RegistryKey作为我的字典的键。

我似乎无法为该特定键设置值。无论我做什么,我都会收到一个KeyNotFoundException错误。该键确实存在,我在一行代码中创建了它。

例如:

public Dictionary<RegistryKey, Dictionary<string, object>> subKeyNodes = new...
subKeyNodes.Add(mainKeyNode.CreateSubKey(keyName),new Dictionary<string, object>());
subKeyNodes[mainKeyNode.CreateSubKey(keyName)].Add("ROAR", "value");

添加操作正常。但使用该键值进行添加操作总是失败,我无法弄清楚是什么问题。

3个回答

5
更好的方法是在字典的构造函数中提供一个实现了IEqualityComparer<RegistryKey>接口的对象,这样就不需要对每个对象进行包装。

4
RegistryKey没有重写GetHashCodeEquals方法。这意味着RegistryKey的实例将使用默认实现(在Object中定义)。因此,即使两个RegistryKey实例的字段相同,它们也不会被视为“相等”。这意味着您不能将此类的实例用作哈希集合(如DictionaryHashSet)的键。
解决方法是定义另一个类,包装RegistryKey并定义这些方法的重写。

谢谢@Paul,我会尝试这个并让你知道。顺便问一下,没有办法强制将GetHashCode或Equals实现到类中吗?我在想像扩展方法那样的东西。 - Reza M.
哇,而且它是封装的 - 我讨厌被迫进行封装。 - payo

2

CreateSubKey每次调用时可能会返回一个新的对象实例。因此,即使它们可能引用同一个注册表键,调用两次将会得到不同的对象。您应该存储第一次调用CreateSubKey的结果,而不是再次调用它。或者使用键名而不是对象作为字典的键。


这只是一个例子,我用了一个变量,结果相同。而且如果CreateSubKey存在,则应该返回该键,否则那将是我的第一个问题。 - Reza M.
仅仅因为打开了相同的注册表键并不意味着它是相同的对象实例。 - BlueMonkMN
你是否考虑使用 Key.Name 作为你的键,而不是键对象? - BlueMonkMN
是的,我之前一直试图避免这样做,以便在需要时可以引用完整的RegistryKey,但由于出现了问题,我完全忘记了它。不过,我将坚持使用包装器,这样我就可以轻松引用RegistryKey,而不必每次都检索它。谢谢+1。 - Reza M.
@RezaM。请记住,注册表键是一次性对象,因此要保持实现的清洁,每个CreateSubKey应该与Close和/或Dispose相匹配。如果您以后还要使用这些相同的实例,那么在将它们放入字典中时,您可能不想关闭这些键。因此,您需要循环遍历字典中的每个键并将其关闭。 - BlueMonkMN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接