c# - 这种情况如何实现GetHashCode?

标签 c# gethashcode

我正在尝试实现 IEqualityComparer<string>它基本上以一种方式比较两个字符串,(假设我们有两个字符串 xy )如果 xy 开头或 yx 开头他们应该被平等对待。

public bool Equals(string x, string y)
{
    return x.StartsWith(y) || y.StartsWith(x);
}

public int GetHashCode(string obj)
{
    return obj.GetHashCode();
}

当然要执行 Equals方法很简单。但是 GetHashCode不是,我想不出任何正确实现它的方法。我写了一个这样的测试程序:

string[] values = {"hell", "hello", "foo", "fooooo"};

var result = values.Distinct(new StringComparer());

foreach(var x in result)
   Console.WriteLine(x);

由于 GetHashCode,我得到了错误的结果:

hell
hello
foo
fooooo

显然我可以强制调用 Equals通过从 GetHashCode 返回相同值的方法对于所有值,但我想知道是否有另一种方法来实现它,因为性能至关重要。有没有办法实现 GetHashCode方法是否适合我的情况?

注意:我知道它含糊不清,但我找不到更好的标题,如果您有更好的想法可以自由编辑。


编辑:我将把这个逻辑与 web url 一起使用。在我的情况下,前 20 个字符是相等的。例如:

http://www.foo.com/bar?id=3
http://www.foo.com/bar?id=3&fooId=23

最佳答案

问题在于您对平等的定义:平等必须是可传递的。但这不是你的情况。取以下三个值:

* f
* freeze
* foo

然后f == freeze,和foo == f,但是freeze != foo

另请参阅 Implementing the Equals Method 上的 MSDN ,它说:

(x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.

正确定义相等会产生不同的值集,这些值被认为是相等的。如果你有那些,你可以为每个集合定义一个“规范”表示并计算规范值的散列,这样每个集合都会有它的散列码。但这仅适用于可传递的操作(以及交换和自反,这两个属性包含在您的定义中)。

由于您对相等性的定义是不可传递的,因此您无法定义此类集合,因此您也无法找到合适的哈希码。

但这也引发了其他问题。以你的例子为例:

string[] values = { "hell", "hello", "foo", "fooooo" };
var result = values.Distinct(new StringComparer());

您希望哪些值进入您的结果?你总是想要最短的版本吗?您的代码无法保证这一点,结果将取决于 Distinct 的内部实现。

实现 EqualityComparer 可能不是解决实际问题的最佳方法。你想达到什么目的?

关于c# - 这种情况如何实现GetHashCode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25524127/

相关文章:

c# - 为什么要异步回调?

c# - 网络核心 : how to make the browser show file as being downloaded before it's sent

c# - asp.net中的语音记录

不使用 GetHashCode 的 HashSet 和 Dictionary 的 C# 高性能替代品

c# - 我是否需要覆盖引用类型的 GetHashCode()?

java - Main.axml打不开VS2015

java - 无法使用 "SecretBox"(C#) 打开 TweetNacl (Java) 生成的 "Libsodium-net"

NHibernate、非复合 ID 和 GetHashCode

c# - 如何使用覆盖 Equals() 的逻辑实现对 GetHashCode() 的覆盖

c# - 有没有办法减少 Equals 和 GetHashCode 中的样板代码量?