イバコの生存記録

いまは競プロ(AtCoder)記事がメインです。

78. IComparable<T> を実装するなら IEquatable<T> も実装した方が良い

C# の話です。今日の仕事でよく分からないバグが発生し、調べていくとこれが原因だった…という経験談です。

 

不具合を調査していくと、独自に作成した「HogeKey」のようなクラスのインスタンスを HashSet に突っ込んでいた箇所で、何故か重複する要素が入っていました。この HogeKey は IComparable<T> を実装するクラスでした。つまり、インスタンス同士に順序が定義できるクラスです。

gist.github.com

 

定義を見直して気付きました。この実装では HashSet で重複判定できないです。期待する挙動を得るには、IEquatable<T> を実装しておく必要があります

 

gist.github.com

 

HashSet や Dictionary では CompareTo ではなく Equals で重複判定が行われます。重複判定には等価性が必要で、順序性は不要なので自然な話です。

逆に、順序性は等価性を暗に含んでいますが、このように C# では順序性のみ定義をすることで、等価性に関して期待に反する挙動を(無意識に)実装できてしまいます

 

IComparable<T> を実装するなら IEquatable<T> は実装しておきましょう…という教訓でした。