WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

匿名型と Distinct メソッド

by WebSurfer 8. December 2015 19:44

IEnumerable<T> で T が匿名型の場合は Distinct() メソッドで期待通り重複のない結果が得られますが、T にカスタムデータ型を使った場合は、

  1. そのカスタムデータ型に IEquatable<T> インターフェイスを継承させて Equals メソッドを実装し、GetHashCode メソッドを override する(具体例は MSDN ライブラリ Enumerable.Distinct<TSource> メソッド (IEnumerable<TSource>) のサンプルコード参照)、または、
  2. IEqualityComparer<T> を継承したクラスを作成し、それを引数にとって値を比較できるバージョンの Distinct メソッドを使う(具体例は MSDN ライブラリ Enumerable.Distinct<TSource> メソッド (IEnumerable<TSource>, IEqualityComparer<TSource>) のサンプルコード参照)。

のいずれかの方法を取る必要があるそうです。知ってました? 実は自分は知らなかったです。匿名型を使っている限りは問題なかったので。(汗)

ちなみに、上に紹介した MSDN ライブラリのサンプルコードで、Product 型に替えて匿名型を使えば以下のように Distinct() メソッドを使って重複しない結果を取得できます。

var products = new[] { 
    new { Name = "apple", Code = 9 }, 
    new { Name = "orange", Code = 4 }, 
    new { Name = "apple", Code = 9 }, 
    new { Name = "lemon", Code = 12 } };

var noduplicates = products.Distinct();

foreach (var product in noduplicates)
    Console.WriteLine(product.Name + " " + product.Code);

/* 結果は:
apple 9
orange 4
lemon 12
*/

ただ、それで何故 Distinct() が使えるのかがズバリ書いてある Microsoft の公式文書が見つからないという不安はありますが。

一応、匿名型における Equals, GetHashCode, ToString メソッドおよび IEquatable<T> インターフェイスの実装について以下の文書があるのは見つけました。

上のコード new { Name = "apple", Code = 9 } で作られる匿名型にも上記が当てはまるのであろうとは思っていますが・・・

(注)VB.NET には Key というキーワードがあってそれを付与して定義したプロパティのみが比較の対象となるようです。一方、C# は上の記事にもあるように全てのプロパティが比較の対象になります。

Tags: ,

.NET Framework

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  January 2020  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar