メモ: LINQのDistinctをオブジェクトに対して使うときはGetHashCodeもオーバーライドする

タイトルで話が終わってしまったけどメモ。

たとえば、先生クラスと部活クラスがあり、部活には先生が1人顧問につく、といった構造があるとします。

public class Teacher
{
    public int Id { get; set; }

    public string Name { get; set; }
}
public class Circle
{
    public int Id { get; set; }

    public string Name { get; set; }

    public Teacher Adviser { get; set; }
}

Teacherクラスのインスタンスは、個々のプロパティが同じ値であれば、同じTeacherを表わすものとして扱うとします。

部活の顧問をしている先生の集合をダブリなく取得したいとき、こんなふうに書きます。

var circles = // (略)IList<Circle>をどこかから取得
var advisers = circles.Select(c => c.Adviser).Distinct().ToList();

このとき、TeacherクラスでEqualsとGetHashCodeの両方をオーバーライドする必要があります。

個々のプロパティが同じ値のときにtrueを返すようなEqualsを実装するだけではダメです。Distinctを指定すると、ダブリのないオブジェクトを取得してしまいます。GetHashCodeも忘れずに。