使列表<学生>与IEquatable <Student>无法区分

Par*_*rsa 3 c# linq distinct iequatable iequalitycomparer

当它存储在List中时,我想让我的Class Sortable(By Age).

我读到这个:IComparable和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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

列出学生=新列表();

//并填补学生

students.Sort();

现在,我想让我的班级有意义,我的意思是当我打电话时.Distinct()它删除重复的学生按ID.

我读IEquatable VS IEqualityComparer 和Sort一样(没有任何争论者)我希望调用.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;
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

列出学生=新列表();

//并填补学生

students.Distinct();

但是,当我使用这个时,没有任何事 为什么?

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

Mat*_*zer 5

看看Enumerable.Distinct文档说:

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

我没看到你的Student班级:

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

另一方面,Enumerable.Distinct回报:

...无序序列,不包含重复值.它使用默认的相等比较器Default来比较值.

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

var x = enumerable.Distinct();
Run Code Online (Sandbox Code Playgroud)

考虑使用 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 }))
{
}
Run Code Online (Sandbox Code Playgroud)