2013-05-21 8 views
10

Mam przypadek, w którym muszę złapać kilka przedmiotów na odrębne, ale moje źródło jest zbiorem obiektów z dwóch właściwości, na przykład:wykonawcze IEqualityComparer <T> na obiekt z dwóch właściwości w C#

public class SkillRequirement 
{ 
    public string Skill { get; set; } 
    public string Requirement { get; set; } 
} 

próbuję dostać zbiór następująco:

SkillRequirementComparer sCom = new SkillRequirementComparer(); 

var distinct_list = source.Distinct(sCom); 

starałem się wdrożyć IEqualityComparer<T> za to, ale upadłem zakłopotany w sposobie GetHashCode().

Klasa dla porównywarka:

public class SkillRequirementComparer : IEqualityComparer<SkillRequirement> 
{ 
    public bool Equals(SkillRequirement x, SkillRequirement y) 
    { 
     if (x.Skill.Equals(y.Skill) && x.Requirement.Equals(y.Requirement)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public int GetHashCode(SkillRequirement obj) 
    { 
     //????? 
    } 
} 

Normalnie bym po prostu użyć GetHashCode() na własność, ale ponieważ jestem porównując na dwie właściwości, jestem trochę w rozterce co zrobić. Czy robię coś złego, czy też brakuje czegoś naprawdę oczywistego?

+0

Zachowaj ostrożność podczas używania 'GetHashCode()', który pochodzi od zmiennych zmiennych! Jeśli umieścisz obiekt w kolekcji mieszania, zmień jedno z pól - ouch. Proponuję uczynienie go niezmiennym. –

+0

Wartości właściwości są pierwotnie z bazy danych, gdzie kolumny nie pozwalają na wartości null, są również sprawdzane dla pustych lub pustych ciągów przed dodaniem obiektu do listy źródłowej, więc nie stanowi to problemu: ^) –

Odpowiedz

10

można zaimplementować GetHashCode w następujący sposób:

public int GetHashCode(SkillRequirement obj) 
{ 
    unchecked 
    { 
     int hash = 17; 
     hash = hash * 23 + obj.Skill.GetHashCode(); 
     hash = hash * 23 + obj.Requirement.GetHashCode(); 
     return hash; 
    } 
} 

originally z J.Skeet

Jeśli właściwości mogą być null należy uniknąć NullReferenceException, np:

int hash = 17; 
hash = hash * 23 + (obj.Skill ?? "").GetHashCode(); 
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode(); 
return hash; 
+1

(Właściwie pochodzi z Josha Blocha;) –

+0

Niezbyt dobry pomysł. Te właściwości są zmienne. –

+0

@ UfukHacıoğulları: Czy możesz określić swoje zastrzeżenia? –

1

Chciałbym połączyć następujące przepełnienie stosu pos ts zbyt chociaż kwestia jest już odpowiedział ..

GetHashCode -

Why is it important to override GetHashCode when Equals method is overridden?

Również w powyższej odpowiedzi Tim Schmelter mówi the properties can be null you should avoid a NullReferenceException

int hash = 17; 
hash = hash * 23 + (obj.Skill ?? "").GetHashCode(); 
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode(); 
return hash; 

IEqualityComparer -

  1. What is the difference between using IEqualityComparer and Equals/GethashCode Override
  2. What's the role of GetHashCode in the IEqualityComparer in .NET?
  3. How and when to use IEqualityComparer in C#

IEquatable - What's the difference between IEquatable and just overriding Object.Equals()?

równa - Guidelines for Overloading Equals()

class TwoDPoint : System.Object 
{ 
    public readonly int x, y; 

    public TwoDPoint(int x, int y) //constructor 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public override bool Equals(System.Object obj) 
    { 
     // If parameter is null return false. 
     if (obj == null) 
     { 
      return false; 
     } 

     // If parameter cannot be cast to Point return false. 
     TwoDPoint p = obj as TwoDPoint; 
     if ((System.Object)p == null) 
     { 
      return false; 
     } 

     // Return true if the fields match: 
     return (x == p.x) && (y == p.y); 
    } 

    public bool Equals(TwoDPoint p) 
    { 
     // If parameter is null return false: 
     if ((object)p == null) 
     { 
      return false; 
     } 

     // Return true if the fields match: 
     return (x == p.x) && (y == p.y); 
    } 

    public override int GetHashCode() 
    { 
     //return x^y; 
    } 
} 
Powiązane problemy