Générer le hachage de l'objet de manière cohérente
Je vais essayer d'obtenir un hash (md5 ou sha) d'un objet.
J'ai mis en place ce:
http://alexmg.com/post/2009/04/16/Compute-any-hash-for-any-object-in-C.aspx
Je suis en utilisant nHibernate pour récupérer mon POCOs à partir d'une base de données.
Lors de l'exécution de GetHash sur ce, c'est différent à chaque fois qu'il est sélectionné et hydraté à partir de la base de données. Je suppose que c'est prévu, comme sous-jacent les procurations changement.
De toute façon,
Est-il un moyen d'obtenir un hachage de toutes les propriétés d'un objet, de façon cohérente à chaque fois?
J'ai joué avec l'idée d'utiliser un StringBuilder au cours de cette.GetType().GetProperties..... et la création d'une table de hachage, mais qui semble inefficace?
Comme une note de côté, c'est pour le suivi des modifications de ces entités à partir d'une base de données (SGBDR) pour un NoSQL magasin
(comparaison des valeurs de hachage pour voir si les objets ont changé entre sgbd et nosql)
Plus d'informations sur la façon dont vous la sérialisation de la désérialisation de ces objets. Et êtes-vous d'écraser GetHashCode()?
OriginalL'auteur Alex | 2012-09-12
Vous devez vous connecter pour publier un commentaire.
Si vous n'êtes pas primordial
GetHashCode
vous venez d'hériterObject.GetHashCode
.Object.GetHashCode
fondamentalement juste retourne l'adresse mémoire de l'instance, si c'est un objet de référence. Bien sûr, chaque fois qu'un objet est chargé, il risque d'être chargé dans une autre partie de la mémoire et ainsi de suite dans un autre code de hachage.On peut se demander si c'est la bonne chose à faire; mais c'est ce qui a été mis en œuvre "retour dans la journée", donc il peut pas changer maintenant.
Si vous voulez quelque chose de cohérent, alors vous devez remplacer
GetHashCode
et de créer un code basé sur la "valeur" de l'objet (c'est à dire les propriétés et/ou des champs). Cela peut être aussi simple que d'une distribué fusion des codes de hachage de toutes les propriétés et les champs. Ou, il pourrait être aussi compliqué que vous le souhaitez.Si tout ce que vous recherchez est quelque chose de différencier deux objets différents, puis à l'aide d'une clé unique sur l'objet pourrait fonctionner pour vous.Si vous êtes à la recherche pour le suivi des modifications, à l'aide de la clé unique pour le hachage ne va pas probablement travailler- Je simplement utiliser tous les codes de hachage des champs à créer un raisonnablement distribué code de hachage de l'objet parent. Par exemple:
L'utilisation du premier numéro 397 est de générer un numéro unique pour une valeur pour mieux distribuer le code de hachage. Voir http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/ pour plus de détails sur l'utilisation des nombres premiers dans le code de hachage de calculs.
Vous pouvez, bien sûr, utiliser la réflexion pour obtenir toutes les propriétés pour ce faire, mais ce serait plus lent. Vous pouvez également utiliser le CodeDOM de générer dynamiquement du code pour générer le hachage basé sur la réflexion sur les propriétés et la mise en cache du code (c'est à dire générer une fois et de le recharger à la prochaine fois). Mais, ce qui bien sûr, est très complexe et pourrait ne pas être en vaut la peine.
Un MD5 ou SHA de hachage ou de CRC est généralement basé sur un bloc de données. Si vous voulez, puis en utilisant le code de hachage de chaque propriété ne fait pas de sens. Éventuellement, la sérialisation des données en mémoire et de calcul de la valeur de hachage qui serait plus applicable, comme Henk décrit.
Object.GetHashCode
ne pas retourner l'adresse de la mémoire de l'instance, car cela peut changer au cours de GC. Il est en fait juste un nombre aléatoire généré lors du premier accès et pointé par l'objet de l'en-tête. Pour plus d'informations, lisez la SyncBlockIndex, qui est utilisé pour le Code de Hachage et de Surveiller, entre autres choses.unchecked
n'a pas de sens ici.Expressions that contain non-constant terms are unchecked by default at compile time and run time. See checked for information about enabling a checked environment.
docs.microsoft.com/en-us/dotnet/csharp/language-reference/...J'ai aussi trouvé des doublons dans les petites séries de données à l'aide de cette méthode (environ 100k éléments, chacun avec environ 30 propriétés qui sont impliqués dans la table de hachage)
gethashcode devrait presque toujours être décochée: csharpindepth.com/viewnote.aspx?noteid=186
Montant de doublons dépend vraiment de données. Un seul algorithme de hachage ne peut pas avoir une répartition idéale pour tous les ensembles de données.
OriginalL'auteur Peter Ritchie
Si ce "hash" est exclusivement utilisé pour déterminer si les entités ont changé alors l'algorithme suivant peut aider (NB il n'est pas testé et suppose que le même runtime sera utilisé lors de la génération de hachages (sinon le recours à GetHashCode pour les "simples" types est incorrect)):
Ce serait alors utilisable comme:
OriginalL'auteur Rich O'Kelly
GetHashCode() renvoie un Int32 (pas un MD5).
Si vous créez deux objets avec les mêmes valeurs de propriété, ils n'auront pas la même valeur de Hachage si vous utilisez la base ou d'un système de GetHashCode().
Chaîne de caractères est un objet et une exception.
Si vous souhaitez contrôler la comparaison d'égalité de deux objets, alors vous devez remplacer le GetHash et de l'Égalité.
Si deux objets sont les mêmes, ils doivent également avoir la même GetHash(). Mais deux objets avec le même GetHash() ne sont pas nécessairement les mêmes. Une comparaison va d'abord tester la GetHash() et si il fait un match là, il permettra de tester l'Égalité. OK il y a quelques comparaisons qui vont droit est Égal, mais vous devez toujours remplacer à la fois et assurez-vous que deux objets identiques produisent les mêmes GetHash.
- Je l'utiliser pour la synchronisation d'un client avec le serveur. Vous pouvez utiliser toutes les Propriétés ou vous pouviez avoir n'importe quel changement de Propriété de modifier le VerID. L'avantage ici est plus simple plus rapide GetHashCode(). Dans mon cas, j'ai été la réinitialisation de la VerID avec tout changement de Propriété déjà.
J'ai fini à l'aide de l'id d'objet seul, afin que je puisse effectuer les opérations suivantes
Objet.Méthode GetHashCode
Deux objets avec les mêmes valeurs de propriété. Sont-ils égaux? Ils produisent le même GetHashCode()?
Mais qu'en est-il de désérialiser utilise le système GetHash et de l'objet avec les mêmes propriétés que n'ont pas les mêmes MD5 parce que d'un hasard GetHash?
Voir la question "Lors de l'exécution de GetHash sur ce, c'est différent à chaque fois qu'il est sélectionné et hydraté à partir de la base de données." OK sérialisation peut pas utiliser GetHashCode, mais l'Objet n'.
OK à mettre en œuvre. Et je suis d'accord ce n'est pas sur la sérialisation. C'est à propos de la GetHashCode produite par un objet.
OriginalL'auteur