.Net字典和等于的重写

时间:2010-11-23 23:17:42

标签: .net dictionary

我知道当我创建一个自定义类作为键的字典时,我提供密钥时的匹配是通过引用比较完成的。例如:

public class SomeClass
{
    public object SomeValue { get; set; }
}

// ....
public static void Main()
{
    var dict = new Dictionary<SomeClass, string>();

    var key1 = new SomeClass { SomeValue = 30 };
    dict[key1] = "30";

    Console.WriteLine(dict[key1]); // prints "30"

    var key2 = new SomeClass { SomeValue = 30 };
    Console.WriteLine(dict[key2]); // prints null 
}

如果我在SomeClass类中重写Equals(和==)会怎样?我会在输出的第二行得到“30”吗?

如果我想要一个基于引用而不是成员值的字典,但是我已经覆盖了Equals会怎样?

谢谢!

1 个答案:

答案 0 :(得分:11)

简答

如果您覆盖EqualsGetHashCode方法,则自定义密钥比较将开始有效。

长答案

Dictionary<TKey,TValue>类不一定进行基于参考的比较。它改为使用可以提供给构造函数的IEqualityComparer<TKey>实例。如果未提供,则默认值为EqualityComparer<T>.Default

EqualityComparer<T>.Default的工作过程很复杂。但总结是

  • 在类型上查找IEquatable<T>,如果存在则用于相等
  • 默认使用Equals方法,默认情况下为Object.Equals,因此参考比较

因此,类型可以在几个级别覆盖比较

  • 指定自定义IEqualityComparer<T>
  • 实施IEquatable<T>并覆盖GetHashCode
  • 覆盖EqualsGetHashCode

等值运算符==!=不会对TKey中的Dictionary<TKey,TValue>类型起作用。