Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
【C#】LINQのDistinctを自作クラスで使うために、IEquatableインタフェースを実装する。
class Program
{
static void Main(string[] args)
{
// シンプルなDistinct
var numbers = new[] { 1, 3, 4, 5, 6, 7, 8, 2, 3, 4, 5, 6, 7 };
Console.WriteLine(string.Join(",", numbers.Distinct().Select(it => it.ToString()).ToArray())); // 1,3,4,5,6,7,8,2
// 自作のクラスでDistinctする場合、IEquatable<T>インタフェースを実装する必要がある。
// 今回は、IDとNameでDistinctされるようにIEquatable<T>インタフェースを実装する。
var cus = new List<Customer>(new[] {
new Customer(1, "endo", "dev1"),
new Customer(2, "endo", "dev2"),
new Customer(1, "endo", "dev3"),
new Customer(4, "endo", "dev4"),
new Customer(5, "endo", "dev5"),
});
var cusDis = cus.Distinct();
Console.WriteLine(string.Join(", ", cusDis.Select(it => it.ToString() + "\r\n").ToArray()));
}
}
// IEquatable<T>を継承する
class Customer : IEquatable<Customer>
{
public int ID { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public Customer(int id, string name) : this(id, name, string.Empty) { }
public Customer(int id, string name, string category)
{
this.ID = id;
this.Name = name;
this.Category = category;
}
public override string ToString()
{
return "IDは:" + this.ID.ToString() + " 名前は:" + this.Name + " 部署は:" + this.Category;
}
// http://msdn.microsoft.com/ja-jp/library/ms131187(v=vs.110).aspx
// Object.Equals(Object)をオーバーライドする場合、オーバーライドされた実装はこのクラス内の静的なEquals(System.Object, System.Object)メソッドの呼び出しでも使用されるらしい。
// 通常、ここは実装しなくても目的の動作はする。
public override bool Equals(object obj)
{
// objがnullか、型が違う時は、等価でない
if (obj == null || this.GetType() != obj.GetType()) {
return false;
}
// IDとNameで比較する。
Customer src = (Customer)obj;
return (this.ID == src.ID && this.Name == src.Name);
}
// GetHashCodeをオーバーライドして実装する。
public override int GetHashCode()
{
// IDとNameのXORを返す。
return this.ID.GetHashCode() ^ this.Name.GetHashCode();
}
#region IEquatable<Customer> メンバ
// IEquatable<T>.Equalsを実装する。
bool IEquatable<Customer>.Equals(Customer other)
{
if (other == null) {
return false;
}
// IDとNameで比較する。
return (this.ID == other.ID && this.Name == other.Name);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment