Când să utilizați un GUID pentru o clasă

I'm working on a simple application with a few classes. This all started when I wanted to use the Remove method on a List. This method requires that you override the Equals and the GetHashCode methods for the Car type. In this situation, I decided to implement an ID property on the Car class. That way, my Equals method simply checks for ID equality, and my GetHashCode method returns base.GetHashCode().

Is this a good approach, or is implementing a GUID for a small class too heavy-handed? There wouldn't be any need for it without the reasons I explained above. The only requirement for uniqueness for this Car type is that it be unique within the List collection to which it belongs. But adding the GUID property seemed like the quickest way around the GetHashCode mess. BTW, there are no int properties on my Car type.

0
Asta este ajutor Adam, mulțumesc; Tocmai am folosit implementarea implicită, dar nu a eliminat niciunul din obiectele din listă. Așa că am început să citesc și să găsesc niște materiale care au făcut să pară că ai nevoie să suprascrieți Equals (), care apoi ți-a cerut să ignori GetHashCode ().
adăugat autor Andrew B Schultz, sursa
Doar pentru a clarifica, metoda Eliminare nu necesită suprascrieri, în mod implicit folosește EqualityComparer .
adăugat autor Adam Houldsworth, sursa

2 răspunsuri

Nu ar fi nevoie de acest lucru fără motivele explicate mai sus.

Dacă clasa dvs. nu are logic un ID, atunci cu siguranță pare ciudat să o includeți doar de dragul egalității.

De exemplu, dacă aveți două instanțe care au proprietăți egale pentru tot cu excepția ID-ului, acestea sunt într-adevăr neegalabile? Dacă acestea sunt, ar trebui să folosiți doar implementarea implicită a Equals / GetHashCode care utilizează identitatea de referință pentru egalitate. În cazul în care utilizați două obiecte cu același ID, utilizați în schimb două referințe la același obiect.

De fapt, totul depinde de context și nu ați dat prea mult din asta - dar adăugarea unui ID doar pentru egalitate este un miros de design.

0
adăugat
Mulțumesc lui John - ceea ce aș face fără ID ar fi să nu accepte două obiecte cu proprietăți egale în aceeași colecție List . Dar obiectivul cu metoda List.Remove ar fi următorul - lista este o proprietate pe un alt tip, îl numim Proprietar. O instanță a proprietarului și a lui List sunt persistente la stocare. Ulterior, ele pot fi recuperate și o mașină poate fi scoasă. Am folosit ID-ul pentru a identifica cel care trebuie eliminat, dar acum că îl menționați, egalitatea de referință va funcționa și pentru asta, deoarece apelantul trebuie să instanțizeze lista înainte de a-l elimina
adăugat autor Andrew B Schultz, sursa

În locul implementării Equals și GetHashCode, folosiți RemoveAll :

myList.RemoveAll(x => x.ID == myCar.ID);

Aceasta vă permite să specificați un predicat care indică în schimb ce elemente ar trebui eliminate (nu contează că eliminați numai un singur element).


Implementarea Equals și GetHashCode în modul pe care îl descrieți mă lovește ca fiind extrem de surprinzător - dacă implementarea dvs. Equals returnează true metoda GetHashCode are nevoie de pentru a reveni la aceeași valoare, astfel încât cele două obiecte să fie plasate în aceeași găleată într-o variantă hashtable. Implementarea dvs. (așa cum o înțeleg) nu corespunde acestor criterii, deoarece implementarea de bază GetHashCode va reveni cu siguranță la diferite valori pentru două instanțe Car , indiferent dacă acestea au aceeași identitate sau nu.

Punerea în aplicare a Equals și GetHashCode nu este în întregime banală și este probabil ceva pe care mi-ar evita în general dacă nu există alternative. Dacă într-adevăr doriți să faceți acest lucru, atunci aruncați o privire la aceste resoruces:

Also hash codes are not GUIDs

0
adăugat
Care parte din întrebarea mea a sugerat că am crezut că un hashcode a fost un guid?
adăugat autor Andrew B Schultz, sursa
O.K. Știu că un GUID nu este un cod hash. GUID a fost conceput pentru a fi folosit în implementarea Equals (), iar suprascrierea GetHashCode() a fost, în mintea mea, pur și simplu o cerință care a crescut de la depășirea metodei Equals (). Am folosit base.GetHashCode pentru că nu știam cum să construiesc un int care ar fi unic din proprietățile mele - de aceea am spus că "nu există proprietăți int pe tipul meu de mașină".
adăugat autor Andrew B Schultz, sursa
@AndrewBSchultz "Este o abordare bună sau este o implementare a unui GUID pentru o clasă mică prea greu?", De asemenea titlul :)
adăugat autor Justin, sursa
@AndrewBSchultz Vedeți răspunsul pentru "Care este cel mai bun algoritm pentru un System.Object.GetHashCode?", Puteți combina codurile hash din alte obiecte (de exemplu, șiruri de caractere) pentru a crea un cod hash unic, de ex. ID.GetHashCode() unde ID este ghidul tău.
adăugat autor Justin, sursa