2010-07-16 11 views
1

Pour un objet avec les propriétés A, B, C, D, StartDate et EndDate si je voulais implémenter quelque chose où deux objets sont égaux s'ils ont A, B et C identiques et qui se chevauchent date, comment cela serait-il fait?Equals, GetHashCode, EqualityComparers et égalité floue

J'ai essayé de créer un EqualityComparer comme si

public override bool Equals(RateItem x, RateItem y) 
    { 
     bool equal = true; 
     if ((x.A != y.A || x.B != y.B || x.C != y.C || 
      (x.StartDate < y.StartDate && x.EndDate <= y.StartDate) || 
      (x.StartDate > y.StartDate && y.EndDate <= x.StartDate))) 
     { equal = false; } 
     return equal; 
    } 

Mais il semble beaucoup d'endroits dans le cadre et l'utilisation Equals ignorer GetHashCode et la documentation n'est pas claire du tout. Quand je vais implémenter GetHashCode je ne sais pas comment rendre les HashCodes identiques sans ignorer les dates. Pour le rendre un peu plus concret, cela a à voir avec la gestion de projet et les tarifs. Je veux implémenter une règle métier que la même personne sur le même projet dans le même rôle ne peut pas avoir des taux différents pendant la même période. Donc Bob sur Project DeathMarch dans le rôle de DBA ne peut avoir qu'un seul taux de facturation effectif à un moment donné pour enregistrer son temps. S'il avait besoin de se connecter quelques heures dans le rôle d'analyste QA à un rythme différent pendant la même période, c'est OK. C'est un système pré-existant massif donc la modification de la structure de l'objet domaine n'est pas une option.

Répondre

2

Ceci n'est pas possible.

L'égalité dans .Net doit être transitive, ce qui signifie que si a == b et b == c, alors a == c.

+0

Vous pouvez définir votre propre 'IsInConflictWith' type de méthode et faire un test de n^2.Une meilleure solution est de tout avoir dans une seule méthode 'DetectConflicts' qui les ordonne par' StartDate' et vérifie ensuite les chevauchements avec un seul passage. –

0

Si vous utilisez les éléments dans une table de hachage alors leur méthode GetHashCode sera utilisé initialement pour tester l'égalité et si leurs hash se trouvent être égale un appel à leur méthode Equals sera faite pour déterminer si elles sont égal.

De la documentation:

« Mais est-ce suffisant pour le Hashtable pour déterminer ils sont identiques objets Malheureusement, pas Si le Hashtable trouve deux objets avec le même hachage,?. il appelle leur méthode Equals pour voir si les deux objets sont en fait égaux.L'implantation par défaut de Object.Equals retournera false si les deux objets sont deux instances différentes de e même classe . Nous devons donc également ajouter un remplacement de la méthode Equals à notre classe.

2

Il est possible. La seule règle pour GetHashCode est que A.GetHashCode() doit être égal à B.GetHashCode() si A == B. Le contraire, si A == B A.GetHashCode() == B.GetHashCode() n'a pas à être vrai.

Ainsi, vous pouvez simplement faire GetHashCode comme si

public override int GetHashCode() 
{ 
    return A.GetHashCode()^B.GetHashCode()^C.GetHashCode(); 
} 

GetHashCode n'est pas d'identité !! Il est utilisé pour regrouper des objets 'similaires'.

Preuve:

string a = "a"; 
string b = "EUKCnPMLpp"; 
Console.WriteLine("a = '{0}', b = '{1}', Same = {2}", a, b, a == b); 
Console.WriteLine("a.GetHashCode() = {0}, b.GetHashCode() = {1}, Same = {2}", a.GetHashCode(), b.GetHashCode(), a.GetHashCode() == b.GetHashCode()); 
+0

Votre première phrase a une erreur. – SLaks

+1

Cela ne va pas aider. Il existe un nombre potentiellement infini d'objets non égaux mais superposés. – SLaks

+0

Il n'y a pas d'erreur de ma part. Votre erreur est dans la confusion de l'identité dans le but de GetHashCode. Si vous allez réfuter la déclaration, donnez un exemple concret. – Tergiver