4

MSDN の記事では、GetHashCode() の既定の実装では一意の結果が保証されないため、識別子として使用しないでくださいしたがって、私の質問は、DateTime.Now に一意のハッシュを提供する独自の実装があるかどうかです。助けてくれてありがとう

4

3 に答える 3

23

まず、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.ToBinaryDateTimeこれにより、一意であり、 (use )を再構成するために使用できる64ビット整数が提供されますDateTime.FromBinary

于 2010-01-01T18:43:58.587 に答える
4

いいえ、そうではありません。

DateTime0001年1月1日以降、その値longを100ナノ秒単位で内部的に格納します。

32ビット整数を返すためGetHashCode、完全に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 に答える