C#中的字典类 - 两个对象的等价

时间:2011-01-04 16:04:50

标签: c# dictionary equals

我有一个名为Class1的类 我重写了它的Equals函数 现在我有一个Dictionary实例 我添加了一个名为OBJ1的Class1实例。 我有另一个名为OBJ2的Class1实例。 对于OBJ1.Equals(OBJ2),代码返回true。 但我在字典中找不到OBJ2。

这是伪代码

Class1 OBJ1 = new Class1(x, y, z);
Class1 OBJ2 = new Class1(a, b, c);
Dictionary<Class1, int> dic1 = new Dictionary<Class1, int>();
dic1.Add(OBJ1, 3);
OBJ1.Equals(OBJ2) -------------> return true
Dictionary.ContainsKey(OBJ2) --------------> return false

为什么会这样? 任何帮助都会受到高度欢迎

7 个答案:

答案 0 :(得分:13)

2种可能性:

  1. GetHashCode未被正确覆盖。您可能需要查看Why is it important to override GetHashCode when Equals method is overriden in C#?
  2. OBJ1在以影响其哈希码的方式添加到字典中后发生了变异。在这种情况下,它所放置的铲斗将不再正确 - ContainsKey将最终在另一个铲斗中搜寻它。
  3. 来自Dictionary<TKey, TValue>

      

    只要将对象用作键   在词典中,它   不得以任何方式改变   影响其哈希值。

答案 1 :(得分:12)

您有可能没有以GetHashCode的方式覆盖Equals

GetHashCode的合同要求如果OBJ1.Equals(OBJ2)返回true,则OBJ1.GetHashCode()必须返回与OBJ2.GetHashCode()相同的值。

IIRC,如果覆盖Equals而不覆盖GetHashCode(),则会收到编译错误(或至少有警告)。

另一种可能性是您实际上没有overridden Equals,但通过添加新签名来重载,例如

public bool Equals(Class1 other)

一般来说,要提供“自然”价值平等比较,您应该:

  • 覆盖等于(对象)
  • 覆盖GetHashCode
  • 强烈考虑实施IEquatable<T>
  • 考虑重载==和!=

答案 2 :(得分:4)

您可能没有在班级中覆盖GetHashcode。当你重写Equals时,你也必须覆盖GetHashcode,否则Dictionary将不适合你。

答案 3 :(得分:3)

您是否也覆盖了GetHashCode? 你能展示Equals方法的实现吗?

答案 4 :(得分:3)

您是否覆盖了GetHashCode

答案 5 :(得分:3)

您还需要覆盖GetHashCode,但也不要忘记您可能需要将自定义Comparer传递给Dictionary构造函数as pointed out in this SO question

答案 6 :(得分:3)

使某些Class1重写GetHashCode()。在比较相等性时,从该方法返回的是第一件事。默认实现对于每个对象都是唯一的。