2011-11-14 3 views
2

2つのプロパティ(int Idとstring Name)を持つMyClassというクラスがあるとします。これらのMyClassオブジェクトのListを別のコレクションから作成したいのですが、固有のコレクションのみを必要とします。この他のコレクションは、値の配列である 'Properties'という名前のプロパティを持つサードパーティオブジェクトです。最初の2つは気になるIdとNameの値に対応しています。このコレクションには重複があるので、私は一意のものだけを求めます。このLINQクエリが期待どおりに機能しないのはなぜですか?

これはトリックを行う必要がありますように思えるが、それは、それは関係なく、dupesのすべてのアイテムを返していません。私はここで間違って何をしていますか?

List<MyClass> items = (from MyClass mc in collectionOfProps 
select new MyClass() { 
Id = collectionOfProps.Properties[0], 
Name = collectionOfProps.Properties[1] }).Distinct().ToList(); 
+0

値はどのような種類がありますか? –

+0

あなたのクエリを見て、それは私によく見えます。 –

答えて

6

問題はMyClassIEquatable<MyClass>だけでなく、オーバーライドEqualsGetHashCodeを実装していない可能性が高いです。

Distinct()を希望通りに動作させるには、IEquatable<T>を実装する必要があります。そうでなければ、チェックのためにデフォルト(参照等価)を使用します。つまり、同じ正確なインスタンスであった場合、要素が区別されていないと判断します。

+0

[このページ](http://blog.jordanterrell.com/post/LINQ-Distinct()-does-ない-作業など-expected.aspxは) 'IEquatable '必ずしも修正されませんを実装する理由を説明しているようです問題は、それ自体の中で。 – Brian

+0

@Brian:彼は 'GetHashCode()'も必要としています。 – SLaks

+0

@SLaks:はい、しかし、 'IEqualityComparer'は(明らかに、*意志*ヘルプタイプにそれを置く)のいずれかの助けにはなりませんに' GetHashCode'を詰めます。とにかく、その記事の人物が「GetHashCode」を避けようとしていて、彼の目標を達成するために少し醜いことを余儀なくされました。あなたがIEquatable ''のためのドキュメントを読めば – Brian

0

MyClassでの等値(別名用)をオーバーライドしましたか?私の推測はノーだろう。ドキュメントによると

http://msdn.microsoft.com/en-us/library/bb348436.aspx

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

1

値を比較するには、Equals()GetHashCode()を上書きする必要があります。

+0

SLAKsは正しいです。少なくとも.Net 4.0では、 'Distinct'は' Set'( 'HashSet'に似た' internal'フレームワーククラス)を使って実装されています。 – Brian

関連する問題