.Net 字典和等号的覆盖

标签 .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(和 ==)会发生什么类(class)?我会在输出的第二行得到“30”吗?

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

谢谢!!

最佳答案

简答

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

长答案
Dictionary<TKey,TValue> class 不一定会进行基于引用的比较。它改为使用 IEqualityComparer<TKey>可以提供给构造函数的实例。如果未提供,则默认值为 EqualityComparer<T>.Default .
EqualityComparer<T>.Default的过程作品复杂。但总结是

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

  • 所以类型可以覆盖几个级别的比较
  • 通过指定自定义 IEqualityComparer<T>
  • 实现 IEquatable<T>和覆盖 GetHashCode
  • 覆盖 EqualsGetHashCode

  • 相等运算符 ==!=TKey 不起作用输入 Dictionary<TKey,TValue> .

    关于.Net 字典和等号的覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4262027/

    相关文章:

    c# - SpeechSynthesizer.SpeakAsync 方法不会立即说话

    c# - 在 C# 中内联使用返回多个值的函数

    jpa - 通过三重联接表在每个 AddressType 的 Person 中定义多个 Address 属性

    c++ - 我无法声明 map

    c++ - 使用 std::map 检查字符串是否包含重复项

    c# - 如何以异步方法向 UI 提供反馈?

    c# - 非静态字段、方法或属性需要对象引用

    c# - 是否可以使用源代码生成器来处理异常?

    python - 将 Python dict 转换为 kwargs?

    使用 locals() 的 Python 字典理解给出 KeyError