Joe*_*Joe 19 c# iequalitycomparer
我正在尝试在两个字符串列表上实现自定义比较器,并使用.Except()linq方法来获取那些不是列表中的一个.我正在做自定义比较器的原因是因为我需要进行"模糊"比较,即一个列表上的一个字符串可以嵌入到另一个列表中的字符串中.
我做了以下比较
public class ItemFuzzyMatchComparer : IEqualityComparer<string>
{
bool IEqualityComparer<string>.Equals(string x, string y)
{
return (x.Contains(y) || y.Contains(x));
}
int IEqualityComparer<string>.GetHashCode(string obj)
{
if (Object.ReferenceEquals(obj, null))
return 0;
return obj.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
当我调试时,唯一的命中断点是在GetHashCode()方法中.Equals()永远不会被触及.有任何想法吗?
Jon*_*eet 18
如果返回的所有哈希码都不同,则永远不需要比较相等性.
基本上问题是你的哈希和相等概念是非常不同的.我不完全确定你是如何纠正这一点的,但是在你这样做之前它肯定是行不通的.
你需要确保if Equals(a, b)返回true,然后GetHashCode(a) == GetHashCode(b).(反过来不一定是真的 - 哈希冲突是可以接受的,尽管显然你希望它们尽可能少.)
正如Jon指出的那样,你需要确保两个相等的字符串的哈希码(根据你的比较规则).这是非常不幸的.
为了演示该问题,Equals(str, "")对所有字符串返回true str,这实质上意味着所有字符串都等于空字符串,因此,所有字符串必须具有与空字符串相同的哈希码.因此,IEqualityComparer正确实现的唯一方法是始终返回相同的哈希码:
public class ItemFuzzyMatchComparer : IEqualityComparer<string> {
bool IEqualityComparer<string>.Equals(string x, string y) {
return (x.Contains(y) || y.Contains(x));
}
int IEqualityComparer<string>.GetHashCode(string obj) {
if (Object.ReferenceEquals(obj, null)) return 0;
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用该Except方法,它将表现正常.唯一的问题是你(可能)会得到一个非常低效的实现,所以如果你需要更好的性能,你可能必须实现自己的Except.但是,我不确定LINQ实现的效率是多么低,而且我不确定实际上是否可以为比较规则提供任何有效的实现.
| 归档时间: |
|
| 查看次数: |
11159 次 |
| 最近记录: |