J’ai besoin de connaître le meilleur moyen de comparer deux objects et de savoir s’ils sont égaux. Je remplace les codes GethashCode et Equals. Donc, un cours de base ressemble à:
public class Test { public int Value { get; set; } public ssortingng Ssortingng1 { get; set; } public ssortingng Ssortingng2 { get; set; } public override int GetHashCode() { return Value ^ Ssortingng1.GetHashCode() ^ Ssortingng2.GetHashCode(); } public override bool Equals( object obj ) { return GetHashCode() == obj.GetHashCode(); } }
Donc, à des fins de test, j’ai créé deux objects:
Test t = new Test() { Value = 1, Ssortingng1 ="One", Ssortingng2 = "One" }; Test t2 = new Test() { Value = 1, Ssortingng1 = "Two", Ssortingng2 = "Two" }; bool areEqual = t.Equals( t2 );
En testant ceci, areEqual renvoie le vrai événement bien que les deux objects soient différents. Je réalise que c’est parce que Ssortingng1 et Ssortingng2 ont la même valeur dans chaque object et s’annulent donc mutuellement lors du hachage.
Existe-t-il un meilleur moyen de hachage d’object que la méthode que j’ai qui résolve mon problème?
Votre méthode d’égalité actuelle est cassée – il y a plus de valeurs que de codes de hachage possibles. Il est tout à fait raisonnable (et attendu) que vous ayez parfois des valeurs inégales mais donnant le même hash. Equals devrait vérifier les valeurs réelles :
public override bool Equals(object obj) { Test test = obj as Test; if (obj == null) { return false; } return Value == test.Value && Ssortingng1 == test.Ssortingng1 && Ssortingng2 == test.Ssortingng2; }
Quelques points à noter:
Votre façon de générer le hashcode donnera la même valeur pour toute Value
fixe si Ssortingng1
et Ssortingng2
sont identiques. il va également exploser si Ssortingng1
ou Ssortingng2
est null. C’est un aspect malheureux de l’utilisation de XOR pour le hachage. Je préfère quelque chose comme ça:
// Put this extension method in a utility class somewhere public static int SafeGetHashCode(this T value) where T : class { return value == null ? 0 : value.GetHashCode(); } // and this in your actual class public override int GetHashCode() { int hash = 19; hash = hash * 31 + Value; hash = hash * 31 + Ssortingng1.SafeGetHashCode(); hash = hash * 31 + Ssortingng2.SafeGetHashCode(); return hash; }
De manière générale, l’égalité devient délicate lorsque l’inheritance est impliqué. Vous voudrez peut-être envisager de sceller votre classe.
Vous pouvez également vouloir implémenter IEquatable
Your Equals
est incorrect – cela devrait définir ce que cela signifie pour deux choses d’être égales – et avoir le même code de hachage ne signifie pas l’ égalité (cependant; un code de hachage différent signifie la non-égalité). Si “égalité” signifie “les deux chaînes sont égales par paires”, alors testez cela.
Re un meilleur hash; xor est notoire pour cela, car il est sortingvial d’obtenir 0 en xor une valeur avec elle-même. Une meilleure approche peut être quelque chose comme:
int i = 0x65407627; i = (i * -1521134295) + Value.GetHashCode(); i = (i * -1521134295) + (Ssortingng1 == null ? 0 : Ssortingng1.GetHashCode()); i = (i * -1521134295) + (Ssortingng2 == null ? 0 : Ssortingng2.GetHashCode()); return i;
simple
Object.Equals(obj1, obj2);
Pour deux objects quelconques, l’égalité d’object implique l’égalité de code de hachage. Toutefois , l’égalité de code de hachage n’implique pas l’égalité d’object. De Object.GetHashCode
sur MSDN:
Une fonction de hachage doit avoir les propriétés suivantes:
Si deux objects se comparent de manière égale, la méthode GetHashCode de chaque object doit renvoyer la même valeur. Toutefois, si deux objects ne se comparent pas comme égaux, les méthodes GetHashCode des deux objects ne doivent pas renvoyer de valeurs différentes.
En d’autres termes, votre Equals
est mal écrit. Cela devrait être quelque chose comme:
public override bool Equals(object obj) { Test other = obj as Test; if (other == null) return false; return (Value == other.Value) && (Ssortingng1 == other.Ssortingng1) && (Ssortingng2 == other.Ssortingng2); }
GetHashCode
aux collections (comme Dictionary
) de déterminer rapidement l’égalité approximative. Equals
sert à comparer si deux objects sont vraiment identiques.
Vous pouvez sérialiser les deux objects en JSON, puis comparer les deux chaînes pour voir si elles sont identiques.
Par exemple
JavaSriptSerializer serialiser = new JavaScriptSerializer(); ssortingng t1Ssortingng = serialiser.Serialize(t); ssortingng t2Ssortingng = serialiser.Serialize(t2); if(t1Ssortingng == t2Ssortingng) return true; //they are equal else return false;
une fonction Equals ne testera-t-elle pas toujours uniquement contre le même type, ne devrait-elle pas être:
//override public bool Equals(Test other)//(object obj) { //return GetHashCode() == obj.GetHashCode(); return (Value == other.Value) && (Ssortingng1 == other.Ssortingng1) && (Ssortingng2 == other.Ssortingng2); }
salutations Oups