我最近以几种不同的方式问过这个问题,但是没有得到一个答案,告诉我当我持有对变化的引用{{1}时,需要如何处理<T,U>
字典。 }}。出于此问题的目的,“状态”指的是在检查T.GetHashCode()
时也检查的属性和字段。假设包括所有公共,内部和受保护的成员。
鉴于我有一个C#对象
覆盖GetHashCode和Equals
此对象作为键值保存到Dictionary中(请注意,我的理解是Dictionary将在此时读取GetHashCode值)
我按键搜索对象并修改一个值。 (修改此值会修改我的自定义等于函数和可能的gethashcode)
我的问题是,GetHashCode应该反映什么?该函数的返回是否应反映对象的原始状态或修改后的状态?
示例代码
Equals()
基于this answer from Jon Skeet(我之前的问题)
“如果我更改最终会更改密钥值的属性,我该怎么办?” - 我
“基本上,你被塞满了。你不会(或者至少可能不会) 能够在你的字典中再次找到该密钥。你应该避免这种情况 尽可能仔细。就个人而言,我通常会发现 适合字典键的类也好 不可变性的候选人。“ - J.S。
这是否意味着我需要从Dictionary中删除对象并重新添加它?这是正确/最好的方式吗?
答案 0 :(得分:2)
好的,所以澄清一下:你正在修改键/值对的键部分。
现在问题很明确,答案相对简单:
这是否意味着我需要从Dictionary中删除对象并重新添加它?
是。 但是 - 您必须在修改它之前将其删除。所以你要写:
testDictionary.Add(keyValue, "some data");
// Do whatever...
testDictionary.Remove(keyValue);
te.EntryName = "modified data";
testDictionary.Add(keyValue, "some data"); // Or a different value...
一般来说,只使用不可变数据结构作为字典键,<em>远风险较小。
另请注意,目前您的Equals
方法依赖于引用所涉及的两个列表的相等性 - 这真的是您想要的吗?另外,您并未覆盖GetHashCode
中的TrustedEntity
,所以即使您 创建了一个具有相同列表的新TrustedEntity
,它也不会给您你想要的结果。基本上,不清楚你想要什么样的平等操作 - 你需要向自己澄清这一点,然后理想地创建所涉及数据的不可变表示。
答案 1 :(得分:1)
GetHashCode()
是否应该改变的问题有点像红鲱鱼。我建议六个公理:
对象的哈希码不改变的要求不是公理之一,而是来自点#1和#6;观察一个与先前观察不同的对象的哈希码将构成一个观察到该对象与其自身不相等。