2010-01-01 3 views
4

L'article MSDN here états, que la mise en œuvre par défaut de GetHashCode() ne garantit pas des résultats uniques et ne devraient pas être utilisé comme identifiant. Donc, ma question est de savoir si DateTime.Now a sa propre implémentation qui donnerait des hachages uniques. Thx pour l'aideEst-ce que DateTime.Now a sa propre implémentation de GetHashCode qui donne des hachages uniques?

+1

La question est formulée un peu étrange. La structure DateTime a une implémentation de GetHashCode(). DateTime.Now est une propriété statique qui renvoie une instance DateTime. – jeroenh

Répondre

20

D'abord, ce serait une erreur de compter sur la mise en œuvre particulière de GetHashCode pour DateTime. C'est quelque chose qui vous est caché. S'appuyer sur des détails cachés est une mauvaise odeur de code; ils pourraient changer sur vous à tout moment et casser votre code.

Ensuite, il s'avère que DateTime stocke en interne un entier de 64 bits DateTime.Ticks qui mesure le nombre d'unités de 100 nanosecondes depuis l'époque (minuit le 1er janvier 0001). Par conséquent, DateTime instances nécessitent au moins 64 bits d'informations. Mais les codes de hachage sont des entiers 32 bits et par conséquent les codes de hachage ne peuvent pas être uniques (vous ne pouvez pas mapper l'espace 64 bits à l'espace 32 bits sans collisions).

Pour être explicite, vous pouvez voir le code source pour DateTime.GetHashCode:

public override int GetHashCode() { 
    long internalTicks = this.InternalTicks; 
    return (((int) internalTicks)^((int) (internalTicks >> 0x20))); 
} 

Comme vous pouvez le voir, il fait un peu « pliage » pour presser InternalTicks dans un entier de 32 bits.

En général, ne comptez pas sur les codes de hachage étant unique. L'espace d'entrée est généralement plus grand que l'espace devant être haché (l'espace de tous les entiers de 32 bits). Si vous devez absolument avoir une clé unique pour représenter un objet DateTime, utilisez DateTime.ToBinary. Cela vous donnera un entier de 64 bits qui est unique et peut être utilisé pour reconstituer le DateTime (utilisation DateTime.FromBinary).

+0

thx beaucoup pour expliquer – Jaker

+0

Un autre détail: 'GetHashCode' ne prend pas en considération la' DateTimeKind' (qui peut être locale, Utc ou non spécifié). 'ToBinary' fait. – Andrew

0

DateTime.Now renvoie une valeur DateTime dont je suis sûr qu'il a sa propre implémentation du code de hachage. Voici la mise en œuvre.

public override int GetHashCode() 
{ 
    long internalTicks = this.InternalTicks; 
    return (((int) internalTicks)^((int) (internalTicks >> 0x20))); 
} 
4

Non, ce n'est pas le cas. Stocke en interne sa valeur sous la forme long contenant unis de 100 nanosecondes depuis le 01/01/0001. Comme GetHashCode renvoie un entier de 32 bits, il est impossible qu'il soit complètement indisponible.

Voici la mise en œuvre de DateTime:

public override int GetHashCode() { 
    Int64 ticks = InternalTicks; 
    return unchecked((int)ticks)^(int)(ticks >> 32); 
} 
+0

Hmmm, Pourquoi la tienne est-elle différente? – ChaosPandion

+0

Je l'ai obtenu à partir du code source de référence. – SLaks

+0

J'ai reçu le mien de Reflector. – ChaosPandion

Questions connexes