此处的 MSDN 文章指出,GetHashCode() 的默认实现不保证唯一的结果,不应用作标识符。所以我的问题是 DateTime.Now 是否有自己的实现,可以给出唯一的哈希值。谢谢帮助
3 回答
首先,依赖 for 的特定实现是错误GetHashCode
的DateTime
。那是对你隐藏的东西。依赖隐藏的细节是不好的代码味道;他们可能随时改变你并破坏你的代码。
其次,事实证明DateTime
内部存储了一个 64 位整数DateTime.Ticks
,用于测量自纪元(0001 年 1 月 1 日午夜)以来 100 纳秒单位的数量。因此,DateTime
实例至少需要 64 位信息。但是哈希码是 32 位整数,因此哈希码不能是唯一的(不能将 64 位空间映射到 32 位空间而不会发生冲突)。
明确地说,您可以查看以下的源代码DateTime.GetHashCode
:
public override int GetHashCode() {
long internalTicks = this.InternalTicks;
return (((int) internalTicks) ^ ((int) (internalTicks >> 0x20)));
}
正如你所看到的,它做了一些“折叠”来压缩InternalTicks
成一个 32 位整数。
一般来说,不要依赖哈希码是唯一的。输入空间通常大于被散列到的空间(所有 32 位整数的空间)。
如果您绝对必须有一个唯一的键来表示一个DateTime
对象,请使用DateTime.ToBinary
. 这将为您提供一个唯一的 64 位整数,可用于重构DateTime
(use DateTime.FromBinary
)。
不,它没有。
DateTime
自 01/01/0001 以来,其值在内部存储为long
包含 100 纳秒的 untis。
由于GetHashCode
返回一个 32 位整数,因此它不可能完全是 unqiue。
这是DateTime
的实现:
public override int GetHashCode() {
Int64 ticks = InternalTicks;
return unchecked((int)ticks) ^ (int)(ticks >> 32);
}
DateTime.Now 返回一个 DateTime 值,我确信它有自己的哈希码实现。这是实现。
public override int GetHashCode()
{
long internalTicks = this.InternalTicks;
return (((int) internalTicks) ^ ((int) (internalTicks >> 0x20)));
}