我想使用日期范围(从一个日期到另一个日期)作为字典的键,所以我编写了自己的结构:
struct DateRange
{
public DateTime Start;
public DateTime End;
public DateRange(DateTime start, DateTime end)
{
Start = start.Date;
End = end.Date;
}
public override int GetHashCode()
{
// ???
}
}
Run Code Online (Sandbox Code Playgroud)
实现GetHashCode的最佳方法是什么,所以没有两个不同范围的对象会生成相同的哈希?我希望哈希冲突尽可能不可能,虽然我理解Dictionary <>仍将检查我将实现的相等运算符,但不想过多地污染示例代码.谢谢!
Mar*_*ers 20
作为乔恩斯基特表明您可以使用从有效的Java方法在这里.对于您的特定类型:
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + Start.GetHashCode();
hash = hash * 23 + End.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
不是为了复活死者,而是我来这里是为了寻找一些东西,对于较新的 C# 版本,你可以这样做
public override int GetHashCode()
{
return HashCode.Combine(Start, End);
}
Run Code Online (Sandbox Code Playgroud)
目前可以在这里找到源: https: //github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/shared/System/HashCode.cs
在我的初步测试中(使用 Jon Skeets 微基准测试框架),就性能而言,它似乎与公认的答案非常相似,即使不一样。
在C# 7你可以这样做:
public override int GetHashCode() => (Start, End).GetHashCode();
Run Code Online (Sandbox Code Playgroud)
该ValueTuple是可用的.NET Framework 4.7和.NET Core,或通过的NuGet。
不确定它的性能如何,但如果任何自定义代码能打败它,我会感到惊讶。
我相信微软在元组中实现GetHashCode()并使用这样的东西而没有任何愚蠢的魔法:
public override int GetHashCode()
{
Tuple.Create(x, y).GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)