2013-05-21 24 views
10

我有一個情況我需要抓住了一堆對不同的項目,但我的源對象具有兩個屬性的集合,像這樣的對象:實現的IEqualityComparer <T> C#中的兩個屬性

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

我試圖得到一個集合,如下所示:

SkillRequirementComparer sCom = new SkillRequirementComparer(); 

var distinct_list = source.Distinct(sCom); 

我試圖實現此一IEqualityComparer<T>,但我摔倒在GetHashCode()方法難倒。

的比較程序類:

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) 
    { 
     //????? 
    } 
} 

通常我只想用GetHashCode()上的屬性,但因爲我比較對兩個屬性,我在做什麼損失感到有點。我做錯了什麼,或者錯過了一些非常明顯的東西?

+0

使用從可變字段派生的'GetHashCode()'時要小心!如果你把對象放在哈希集合中,那麼改變其中一個字段 - ouch。我建議讓它不可變。 –

+0

屬性的值原本來自數據庫,其中列不允許爲空值,因此在將對象添加到源列表之前還會檢查空字符串或空字符串,因此它不是一個問題:^) –

回答

10

您可以實現下列方式GetHashCode

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

originally從J.Skeet

如果屬性可以null你應該避免NullReferenceException,如:

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

(其實它最初來自Josh Bloch;) –

+0

不是一個好主意。這些屬性是可變的。 –

+0

@UfukHacıoğulları:你能指出你的異議嗎? –

1

我想鏈接下面的堆棧溢出pos TS太雖然問題已經回答了..

的GetHashCode -

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

此外,在上述答案添Schmelter說: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()?

的Equals - 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; 
    } 
} 
相關問題