2015-01-31 92 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