Dictionary.Equals()有实现吗?

我有一个字典,我将其与另一个字典进行比较(变量类型为IDictionary)。 执行d1.Equals(d2)会产生错误。 在下面编写自己的代码会产生真实。 两者都是System.Collections.Generic.Dictionary 。 我错过了什么或者Dictionary没有比较键/值的Equals实现吗?

 private static bool DictEquals(IDictionary d1, IDictionary d2) { if (d1.Count != d2.Count) return false; foreach (KeyValuePair pair in d1) { if (!d2.ContainsKey(pair.Key)) return false; if (!Equals(d2[pair.Key], pair.Value)) return false; } return true; } 

Dictionary.Equals()使用默认的Equals from Object,检查两个对象是否与所有其他默认集合相同。 您可以自由地创建具有值语义的子类,尽管这通常包括不可变的内容。

可能Dictionary类的Equals方法只是转向从Objectinheritance的默认实现,也就是说,它只是比较传递的Dictionary对象引用和它自己的引用。 请参见此处: Object.Equals参考

假设两个字典,一个是SortedList和一个Dictionary ,进行相等比较,如果项目相同,它真的会返回true吗? 这将是非常糟糕的,因为它们具有不同的特征和特征(例如, SortedList<,>允许通过索引进行检索)。

此外,相等和哈希代码在逻辑上绑在一起。 哈希码应该是不可变的,否则所有基于哈希的算法都不起作用。 当您使用内容检查相等性时,您无法保证这一点。 因此,默认实现(检查它们是否是同一个实例)是非常合理的。 您可以自由创建自己的内容平等比较。

其他人提到它正在使用Object.Equals实现,您可以使用以下内容来覆盖它:

 public class EqualsDictionary : Dictionary { public override bool Equals(object obj) { //Place your comparison implementation here } } 

除了封装对象状态的不可变方面之外,.NET中的引用可用于封装对象的标识,其状态的可变方面,两者或两者。 通常,如果没有特别的理由不这样做,.NET假定对可变对象的引用用于封装标识。 它进一步假设,在代码比较引用而不知道它们代表什么的情况下,最好在报告不平等的事情时犯错误。 因此,当且仅当它们标识相同的对象时,对可变对象的两个引用通常被认为是等价的,因此不鼓励使用可变类型来覆盖Equals指示任何其他对象。 相反,使用引用来封装可变状态的代码应该使用除Object.Equals()之外的一些方法来比较它们。