MSDN の記事では、GetHashCode() の既定の実装では一意の結果が保証されないため、識別子として使用しないでください。したがって、私の質問は、DateTime.Now に一意のハッシュを提供する独自の実装があるかどうかです。助けてくれてありがとう
3 に答える
まず、forの特定の実装に依存するのは間違いGetHashCode
ですDateTime
。それはあなたから隠されているものです。隠された詳細に依存することは、悪いコードの臭いです。彼らはいつでもあなたを変えてあなたのコードを壊す可能性があります。
次に、エポック(0001年1月1日の深夜)以降の100ナノ秒単位の数を測定DateTime
する64ビット整数を内部に格納していることがわかります。DateTime.Ticks
したがって、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
。DateTime
これにより、一意であり、 (use )を再構成するために使用できる64ビット整数が提供されますDateTime.FromBinary
。
いいえ、そうではありません。
DateTime
0001年1月1日以降、その値long
を100ナノ秒単位で内部的に格納します。
32ビット整数を返すためGetHashCode
、完全に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)));
}