c # Comment trouver si deux objects sont égaux

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