2015-01-31 86 views
1

我已經爲我的自定義類實現了一個比較類,以便我可以在兩個列表(StudentList1StudentList2)上使用Intersect。但是,當我運行下面的代碼時,我沒有得到任何結果。LINQ Intersect不返回項目

學生:

class CompareStudent : IEqualityComparer<Student> 
{ 
    public bool Equals(Student x, Student y) 
    { 
     if (x.Age == y.Age && x.StudentName.ToLower() == y.StudentName.ToLower()) 
      return true; 
     return false; 
    } 

    public int GetHashCode(Student obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

class Student 
{ 
    public int StudentId{set;get;} 
    public string StudentName{set;get;} 
    public int Age{get;set;} 
    public int StandardId { get; set; } 
} 

主營:

IList<Student> StudentList1 = new List<Student>{ 
       new Student{StudentId=1,StudentName="faisal",Age=29,StandardId=1}, 
       new Student{StudentId=2,StudentName="qais",Age=19,StandardId=2}, 
       new Student{StudentId=3,StudentName="ali",Age=19} 
      }; 
IList<Student> StudentList2 = new List<Student>{ 
       new Student{StudentId=1,StudentName="faisal",Age=29,StandardId=1}, 
       new Student{StudentId=2,StudentName="qais",Age=19,StandardId=2}, 

      }; 

var NewStdList = StudentList1.Intersect(StudentList2, new CompareStudent()); 

Console.ReadLine(); 
+0

感謝編輯@Nate – 2015-02-01 05:39:36

回答

3

的問題是你的GetHashCode()方法中,將其更改爲:

public int GetHashCode(Student obj) 
{ 
    return obj.StudentId^obj.Age^obj.StandardId^obj.StudentName.Length; 
} 

在你CURREN T代碼,Equals不叫作爲當前GetHashCode()返回兩個不同的整數,所以在調用Equals沒有意義的。

如果第一個對象的GetHashCode與第二個對象不同,則對象不相等,如果結果相同,則調用Equals

GetHashCode我上面寫的不是最終的,關於如何實現GetHashCode的更多細節請見What is the best algorithm for an overridden System.Object.GetHashCode?

GetHashCode()is not(而且不能)無碰撞,這就是爲什麼首先需要Equals方法的原因。

+3

我喜歡(和使用)從線程此實現你鏈接:http://stackoverflow.com/a/18613926/3191599 – 2015-01-31 19:17:39

+0

嗨, Ofiris。首先感謝解決方案。我也嘗試過使用特定的ComparStudent類的Contains,並返回obj的GetHashCode(),但它在特定的語句中運行正常。我是否需要爲Conatns使用特定的解決方案,或者它在當前情景中的行爲有所不同。 Student std = new Student {StudentName =「faisal」,年齡= 29}; bool result3 = StudentList.Contains(std,new CompareStudent()); – 2015-02-01 05:35:55

+0

是,同樣的答案是相關的'Contains': 'StudentList2.Contains(新學生{StudentId = 2,StudentName = 「卡伊斯」,年齡= 19,StandardId = 2},新CompareStudent())// TRUE' – Ofiris 2015-02-01 06:29:12

1

您呼叫的基本對象,這將返回不同的值不同的引用上GetHashCode()。我想實現這樣的:

public override int GetHashCode(Student obj) 
    { 
     unchecked 
     { 
      return obj.StudentName.GetHashCode() + obj.Age.GetHashCode(); 
     } 
    } 
+0

+1。但考慮到有一個'StudentId'屬性,它可以唯一地標識一個學生,爲什麼不使用那個(而不是'StudentName'和'Age')來計算散列呢? 'return obj.StudentId.GetHashCode();'(沒有'unchecked')就足夠了。 – stakx 2015-02-01 06:39:08

+0

最初的問題沒有在平等執行中使用學生ID,所以我認爲他們不打算將其用於平等。 – 2015-02-01 13:42:37