gpt4 book ai didi

c# - GetHashCode 在 .NET 中的 IEqualityComparer 中的作用是什么?

转载 作者:IT王子 更新时间:2023-10-29 03:32:51 25 4
gpt4 key购买 nike

我试图了解接口(interface) IEqualityComparer 的 GetHashCode 方法的作用。

以下例子摘自MSDN:

using System;
using System.Collections.Generic;
class Example {
static void Main() {
try {

BoxEqualityComparer boxEqC = new BoxEqualityComparer();

Dictionary<Box, String> boxes = new Dictionary<Box,
string>(boxEqC);

Box redBox = new Box(4, 3, 4);
Box blueBox = new Box(4, 3, 4);

boxes.Add(redBox, "red");
boxes.Add(blueBox, "blue");

Console.WriteLine(redBox.GetHashCode());
Console.WriteLine(blueBox.GetHashCode());
}
catch (ArgumentException argEx) {

Console.WriteLine(argEx.Message);
}
}
}

public class Box {
public Box(int h, int l, int w) {
this.Height = h;
this.Length = l;
this.Width = w;
}
public int Height { get; set; }
public int Length { get; set; }
public int Width { get; set; }
}

class BoxEqualityComparer : IEqualityComparer<Box> {

public bool Equals(Box b1, Box b2) {
if (b1.Height == b2.Height & b1.Length == b2.Length
& b1.Width == b2.Width) {
return true;
}
else {
return false;
}
}

public int GetHashCode(Box bx) {
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
}
}

Equals 方法的实现是否足以比较两个 Box 对象?这就是我们告诉框架用于比较对象的规则的地方。为什么需要 GetHashCode?

谢谢。

卢锡安

最佳答案

先介绍一下背景......

.NET 中的每个对象都有一个 Equals 方法和一个 GetHashCode 方法。

Equals 方法用于将一个对象与另一个对象进行比较 - 查看这两个对象是否相等。

GetHashCode 方法生成对象的 32 位整数表示。由于一个对象可以包含多少信息没有限制,某些散列码由多个对象共享 - 因此散列码不一定是唯一的。

字典是一种非常酷的数据结构,它以更高的内存占用换取(或多或少)添加/删除/获取操作的恒定成本。但是,迭代是一个糟糕的选择。在内部,字典包含一个存储桶数组,其中可以存储值。将键和值添加到字典时,会在键上调用 GetHashCode 方法。返回的哈希码用于确定应存储键/值对的存储桶的索引。

当你想访问Value时,你再次传入Key。在Key上调用GetHashCode方法,定位到包含Value的bucket。

将 IEqualityComparer 传递到字典的构造函数时,将使用 IEqualityComparer.Equals 和 IEqualityComparer.GetHashCode 方法,而不是 Key 对象上的方法。

现在解释为什么这两种方法都是必要的,考虑这个例子:

BoxEqualityComparer boxEqC = new BoxEqualityComparer(); 

Dictionary<Box, String> boxes = new Dictionary<Box, string>(boxEqC);

Box redBox = new Box(100, 100, 25);
Box blueBox = new Box(1000, 1000, 25);

boxes.Add(redBox, "red");
boxes.Add(blueBox, "blue");

在您的示例中使用 BoxEqualityComparer.GetHashCode 方法,这两个框都具有相同的哈希码 - 100^100^25 = 1000^1000^25 = 25 - 尽管它们显然不是同一个对象。在这种情况下,它们是相同哈希码的原因是因为您使用的是 ^(按位异或)运算符,所以 100^100 抵消掉留下零,1000^1000 也是如此。当两个不同的对象具有相同的键时,我们称之为碰撞。

当我们将具有相同哈希码的两个键/值对添加到字典时,它们都存储在同一个桶中。因此,当我们想要检索一个 Value 时,会在我们的 Key 上调用 GetHashCode 方法来定位桶。由于存储桶中有多个值,字典会遍历存储桶中的所有键/值对,对键调用 Equals 方法以找到正确的值。

在您发布的示例中,两个框是等价的,因此 Equals 方法返回 true。在这种情况下,字典有两个相同的键,因此会抛出异常。

TLDR

所以综上所述,GetHashCode方法就是用来生成一个存放对象的地址的。所以字典不必搜索它。它只是计算哈希码并跳转到该位置。 Equals 方法是一种更好的相等性测试,但不能用于将对象映射到地址空间。

关于c# - GetHashCode 在 .NET 中的 IEqualityComparer<T> 中的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4095395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com