IEquatable<T>インターフェースを用いて独自の等価比較を行う。
はじめに
IEquatable
通常の比較
通常クラスのインスタンスでは参照の等価比較が行われます。 参照の等価比較のため、例えば以下のプログラムでは結果は「0」になります。
public class Program { static void Main() { var sample1List = new List<Sample>(){ new Sample { SampleId = 1, SampleText = "Test1" }}; var sample2List = new List<Sample>(){ new Sample { SampleId = 1, SampleText = "Test1" }}; var intersectList = sample1List.Intersect(sample2List).ToList(); Console.WriteLine(intersectList.Count); } } public sealed class Sample { public int SampleId { get; set; } public string SampleText { get; set; } }
※Intersectメソッドは2つのシーケンスの積集合を生成します。
Enumerable.Intersect メソッド (System.Linq) | Microsoft Docs
IEquatableインターフェースを実装後の比較
独自の等価比較を行う場合は比較対象のクラスにIEquatable\
public class Program { static void Main() { var sample1List = new List<Sample>(){ new Sample { SampleId = 1, SampleText = "Test1" }}; var sample2List = new List<Sample>(){ new Sample { SampleId = 1, SampleText = "Test1" }}; var intersectList = sample1List.Intersect(sample2List).ToList(); Console.WriteLine(intersectList.Count); } } public sealed class Sample : IEquatable<Sample> { public int SampleId { get; set; } public string SampleText { get; set; } public bool Equals(Sample other) { if(other == null) return false; return SampleId == other.SampleId; } public override bool Equals(object obj) { if(obj is Sample sample) return Equals(sample); return false; } public override int GetHashCode() => 0; }
※ちなみに上記のコードだとSampleIdだけで等価比較を行っているので、例えばSampleIdが1でSampleTextが"Test2"の場合も等価と見なされます。
おわりに
比較は色々と手法があるので覚えるのが大変ですが、しっかり使いこなしていきたいです。