我有一个字典,我将其与另一个字典进行比较(变量类型为IDictionary)。执行d1.Equals(d2)会产生错误。在下面编写自己的代码会产生真实。两者都是System.Collections.Generic.Dictionary
。我错过了什么或者Dictionary
没有Equals
实施来比较键/值吗?
private static bool DictEquals<K, V>(IDictionary<K, V> d1, IDictionary<K, V> d2)
{
if (d1.Count != d2.Count)
return false;
foreach (KeyValuePair<K, V> pair in d1)
{
if (!d2.ContainsKey(pair.Key))
return false;
if (!Equals(d2[pair.Key], pair.Value))
return false;
}
return true;
}
答案 0 :(得分:12)
Dictionary.Equals()使用默认的Equals from Object,检查两个对象是否与所有其他默认集合的引用相同。您可以使用值语义自由创建自己的子类,但通常也包含不可变的内容。
答案 1 :(得分:5)
Equals
类的Dictionary
方法可能只是转向从Object
继承的默认实现,也就是说,它只是比较传递给它的Dictionary
对象引用自己的参考。见这里:Object.Equals reference
答案 2 :(得分:2)
假设两个词典(一个是SortedList<TKey, TValue>
和一个Dictionary<TKey, TValue>
)进行相等性比较,如果项目相同,它真的会返回true吗?这将是非常糟糕的,因为它们具有不同的特征和特征(例如SortedList<,>
允许通过索引进行检索)。
此外,相等和哈希码在逻辑上绑在一起。哈希码应该是不可变的,否则所有基于哈希的算法都不起作用。当您使用内容检查相等性时,您无法保证这一点。因此,默认实现(检查它们是否是同一个实例)是非常合理的。您可以自由创建自己的内容平等比较。
答案 3 :(得分:1)
其他人提到它正在使用Object.Equals实现,您可以使用以下内容来覆盖它:
public class EqualsDictionary<T, T> : Dictionary<T, T>
{
public override bool Equals(object obj)
{
//Place your comparison implementation here
}
}
答案 4 :(得分:0)
除了封装对象状态的不可变方面之外,.NET中的引用可用于封装对象的标识,其状态的可变方面,两者或两者。通常,如果没有特别的理由假设其他情况,.NET假定对可变对象的引用用于封装标识。它进一步假设,在代码比较引用但不知道它们代表什么的情况下,最好在报告不平等的事情时犯错误。因此,当且仅当它们标识相同的对象时,对可变对象的两个引用通常被认为是等效的,因此不鼓励可变类型覆盖Equals
以指示其他任何内容。相反,使用引用来封装可变状态的代码应使用除Object.Equals()
之外的其他方法来比较它们。