Created
April 10, 2014 03:07
-
-
Save yoshikazuendo/10339499 to your computer and use it in GitHub Desktop.
【C#】LINQのDistinctを自作クラスで使うために、IEquatableインタフェースを実装する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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