我正在尝试实现 IEqualityComparer<string>
它基本上以一种方式比较两个字符串,(假设我们有两个字符串 x
和 y
)如果 x
以 y
开头或 y
以 x
开头他们应该被平等对待。
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 ifx.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/