4

此处的 MSDN 文章指出,GetHashCode() 的默认实现不保证唯一的结果,不应用作标识符。所以我的问题是 DateTime.Now 是否有自己的实现,可以给出唯一的哈希值。谢谢帮助

4

3 回答 3

23

首先,依赖 for 的特定实现是错误GetHashCodeDateTime。那是对你隐藏的东西。依赖隐藏的细节是不好的代码味道;他们可能随时改变你并破坏你的代码。

其次,事实证明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)。

于 2010-01-01T18:43:58.587 回答
4

不,它没有。

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); 
}
于 2010-01-01T18:40:36.670 回答
0

DateTime.Now 返回一个 DateTime 值,我确信它有自己的哈希码实现。这是实现。

public override int GetHashCode()
{
    long internalTicks = this.InternalTicks;
    return (((int) internalTicks) ^ ((int) (internalTicks >> 0x20)));
}
于 2010-01-01T18:38:34.947 回答