使列表<student>与IEquatable <student>无法区分

时间:2017-02-18 20:42:00

标签: c# linq distinct iequalitycomparer iequatable

我想在List中存储我的Class Sortable(By Age)。

我读到了这个:IComparable Vs IComparer我制作了我的班级Sortable。

public class Student : IComparable<Student>
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public int CompareTo(Student other)
    {
        if (this.Age > other.Age)
        {
            return 1;
        }
        else if (this.Age < other.Age)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }
}
  

列出学生=新名单();

     

//并填写学生

     

students.Sort();

现在,我想让我的课堂明白,我的意思是当我打电话时.Distinct()它会删除重复的学生ID。

我看了IEquatable VS IEqualityComparer 和排序(没有任何争论者)一样,我希望调用.Distinct()而不会传递任何争论者。

public class Student : IEquatable<Student>
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public bool Equals(Student other)
        {
            if (this.ID == other.ID)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
}
  

列出学生=新名单();

     

//并填写学生

     

students.Distinct();

但是当我用它时没有发生任何事情。 为什么?

我如何实现IEquatable并使用Distinct()而不传递争论者?

3 个答案:

答案 0 :(得分:5)

查看Enumerable.Distinct&#39; s docs says

  

默认的相等比较器Default用于比较的值   实现IEquatable泛型接口的类型。至   比较自定义数据类型,您需要实现此接口和   为类型提供自己的GetHashCode和Equals方法。

我没有看到你的Student课程:

  • ...覆盖Object.GetHashCode(...)
  • ...覆盖Object.Equals(...)

另一方面,Enumerable.Distinct返回:

  

...无序序列,不包含重复值。它使用了   default equality comparer,Default,比较值。

因此,您需要将结果设置为变量:

var x = enumerable.Distinct();

考虑使用HashSet<T>

也许您希望您的收藏集包含唯一元素。如果是这种情况,请不要将元素存储在常规集合中,以便稍后调用Enumerable.Distinct(),但直接使用HashSet<T>

一旦您修复了Student课程,覆盖了上述所有方法,您就可以按如下方式存储学生:

HashSet<Student> studentSet = new HashSet<Student();
studentSet.Add(new Student { ID = 1, Name = "Matías", Age = 32 });

// HashSet<T>.Add returns true if it could add the whole element. 
// In our case, this if statement will never enter!
if(studentSet.Add(new Student { ID = 1, Name = "Matías", Age = 32 }))
{
}

答案 1 :(得分:3)

与所有其他LINQ方法一样,返回值而不是修改原始集合。

修复 - 将结果作为变量或ToList的结果并分配给学生。

答案 2 :(得分:0)

您应该实施 IEquable 界面并覆盖等于 GetHashCode 方法。