.Net字典和等于的重写

Bru*_*ant 7 .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 
}
Run Code Online (Sandbox Code Playgroud)

如果我在SomeClass类中重写Equals(和==)会发生什么?我会在输出的第二行得到"30"吗?

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

谢谢!!

Jar*_*Par 11

简答

是,如果您覆盖EqualsGetHashCode方法,您的自定义键比较将开始工作.

答案很长

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

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

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

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

  • 通过指定自定义 IEqualityComparer<T>
  • 实施IEquatable<T>和覆盖GetHashCode
  • 重写EqualsGetHashCode

等于运算符==并且!=不用于a中的TKey类型Dictionary<TKey,TValue>.