在.NET GetHashCode方法中,很多地方都使用.NET 方法.特别是在快速查找集合中的项目或确定相等性时.是否有关于如何GetHashCode为我的自定义类实现覆盖的标准算法/最佳实践,因此我不会降低性能?
背景:
我们希望能够在查询中快速匹配这些字符串,而不会影响大量连接.
所以我想在主表中存储所有这些字符串的哈希码并将其包含在索引中,因此只有当哈希码匹配时才会由数据库处理连接.
那么我如何获得一个好的哈希码呢?我可以:
那人们怎么想?
最后,我只是连接字符串并计算连接的哈希码,因为它很简单并且工作得很好.
(如果你关心我们使用的是.NET和SqlServer)
Bug!,Bug!
引自 Eric Lippert的GetHashCode指南和规则
System.String.GetHashCode的文档特别指出,两个相同的字符串在CLR的不同版本中可以具有不同的哈希码,实际上它们也是如此.不要在数据库中存储字符串哈希并期望它们永远是相同的,因为它们不会.
所以不应该使用String.GetHashcode().
public class Address{
public string ContactName {get; private set;}
public string Company {get; private set;}
//...
public string Zip {get; private set;}
}
Run Code Online (Sandbox Code Playgroud)
我想实现一个distint地址的概念,所以我重写了Equals()来测试所有字段中不区分大小写的相等性(因为这些是US地址,我使用Ordinal而不是InvariantCulture来获得最大性能):
public override bool Equals(Object obj){
if (obj == null || this.GetType() != obj.GetType())
return false;
Address o = (Address)obj;
return
(string.Compare(this.ContactName, o.ContactName, StringComparison.OrdinalIgnoreCase) == 0) &&
(string.Compare(this.Company, o.Company, StringComparison.OrdinalIgnoreCase) == 0)
// ...
(string.Compare(this.Zip, o.Zip, StringComparison.OrdinalIgnoreCase) == 0)
}
Run Code Online (Sandbox Code Playgroud)
我想像这样写一个GetHashCode()(暂时忽略连接效率低下):
public override int GetHashCode(){
return (this.contactName + this.address1 + this.zip).ToLowerOrdinal().GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
但那不存在.我应该用什么呢?或者我应该在我的Equals()方法中使用InvariantCulture?
(我在想.ToLowerInvariant().GetHashCode() …
我在.NET4中使用短字符串的哈希冲突有问题.
编辑:我在.NET中使用内置的字符串散列函数.
我正在使用存储转换方向的对象来实现缓存
public class MyClass
{
private string _from;
private string _to;
// More code here....
public MyClass(string from, string to)
{
this._from = from;
this._to = to;
}
public override int GetHashCode()
{
return string.Concat(this._from, this._to).GetHashCode();
}
public bool Equals(MyClass other)
{
return this.To == other.To && this.From == other.From;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (this.GetType() != obj.GetType()) return false;
return Equals(obj as MyClass);
}
} …Run Code Online (Sandbox Code Playgroud)