LoginSignup
29

More than 5 years have passed since last update.

C# LINQ Distinct を自作クラスのコレクションで使う方法

Last updated at Posted at 2015-04-22

自作のクラスを保持するコレクションに対し LINQ の Distinct を使う場合、IEquatableインターフェースを実装する必要があるってことで、いろいろハマったのでメモ。

自作のクラスがこんな感じだったとする


public class MyModel
{
        public string ItemID { get; set; }
        public string ItemName { get; set; }

        public MyModel(string ItemID, string ItemName)
        {
                this.ItemID = ItemID;
                this.ItemName = ItemName;
        }
}

List<MyModel> に対し Distinct をしても動かない


List<MyModel> myModels = new List<MyModel>();

//
// もろもろ過程を経て、myModel にデータが格納されていると過程して
//

myModels = myModels.Distinct().ToList(); // 重複削除は行われない

まー、動かないかなーって思ってたけど(例えば何をもって重複と判断するのか的な)、これを思った通りの動きにする場合、MyModelクラスに IEquatable インターフェースを実装する

実装の例

この IEquatable を実装する場合、GetHashCode を override することと、Equals メソッドを実装する必要があるようです(ソースについては後述)


public class MyModel : IEquatable<MyModel>
{
        public string ItemID { get; set; }
        public string ItemName { get; set; }

        public MyModel(string ItemID, string ItemName)
        {
                this.ItemID = ItemID;
                this.ItemName = ItemName;
        }

        public override int GetHashCode()
        {
                return this.ItemID.GetHashCode();
        }

        bool IEquatable<MyModel>.Equals(MyModel myModel)
        {
                if( myModel == null )
                        return false;
                return (this.ItemID == myModel.ItemID);
        }
}

こうすることで、期待通りの動きになった。

ソース

Microsoft Developer Network Enumerable.Distinct メソッド

既定の等値比較子 Default は、IEquatable ジェネリック インターフェイスを実装している型の値を比較するために使用されます。 カスタム データ型を比較するには、このインターフェイスを実装し、その型の GetHashCode メソッドと Equals メソッドを独自に用意する必要があります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29