2009-10-30 81 views
9

我有一个字典,我正在比较另一个字典(变量类型为IDictionary)。做d1.Equals(d2)产生错误。写下我自己的代码产生真实。两者都是System.Collections.Generic.Dictionary。我是否缺少一些东西,或者Dictionary没有一个Equals实现比较键/值?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; 
} 

回答

10

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

+2

+1,正如它在Dictionary类文档中所述。 http://msdn.microsoft.com/en-us/library/3eayzh46.aspx。 – 2009-10-30 14:12:48

5

也许Dictionary类的Equals方法简单地诉诸默认实现从继承Object,也就是说,它只是比较有自己的引用传递的Dictionary对象引用。请参阅:Object.Equals reference

1

其他人所说的,它使用的Object.Equals实现,可以使用以下方法来覆盖它:

public class EqualsDictionary<T, T> : Dictionary<T, T> 
{ 
    public override bool Equals(object obj) 
    { 
     //Place your comparison implementation here 
    } 
} 
+2

要*覆盖它,就像关键字说的那样。重载是不同的。 – Joren 2009-10-30 14:16:45

+0

@Joren:是的,对我来说还为时过早。 – 2009-10-30 14:25:56

2

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

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

+0

公平点,我上面的代码应该比较内容之前进行通常的身份+班级比较检查。 – 2009-10-30 14:24:53

+0

对。然而,由于散列码的问题,这仍然不适合替换Equals():如果两个对象相等,则它们的散列码必须相等,并且散列码必须是不可变的。结果,Equals()可能不会仅仅因为两个集合具有相同内容的相同类型而返回true,因为它们仍然会有不同的(不可变的,难以强调的)哈希码。 – Lucero 2009-11-01 23:57:28

+0

@Lucero:这太糟糕了。NET只定义了一组虚拟等价关系方法,因为大多数“不可变”的类类型持有对可能会变的对象的引用,除了引用永远不会暴露给可能会改变它们的任何东西*并且如果有的话是那些不可变包装类可以用来对其内容进行哈希或校验相等的标准方法。 – supercat 2013-11-03 20:46:25

0

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

相关问题