2012-01-06 8 views
5

Dictionaryのキーは、同等である必要がありますか?私の場合はC#辞書の平等要件

例えば

Class mytype 
{ 
    public bool equals(mytype other) 
    { 
     return ...; 
    } 
} 

彼らは同じインスタンスでない限り、彼らは同じではありません。

同等性を実装する必要がある場合、mytypeの新しいインスタンスが1つ増えたときに増分する大きな数値を作成する必要がありますか?

答えて

3

クラスが同じインスタンスの場合は、equalしかない場合は、Dictionaryでクラスを使用するために何もする必要はありません。クラス(参照型)は、同じオブジェクトを参照する場合に限り等しく見なされます。オブジェクトの派生クラスの

From the documentation of GetHashCode

とその派生クラスが参照平等型に値の等価性を定義する場合にのみ、値型でない場合、GetHashCodeメソッドは、Object.GetHashCodeを実装に委任することができ。

あなたのケースでは本当のようです。経験則として、あなたはあなたにもGetHashCodeメソッドをオーバーライドする必要がありますが、デフォルトでは、あなたが探しているものであるとして、これはあなたの場合には必要ありません均等をオーバーライドします。

+0

ありがとうございました。 – alan2here

1

デフォルトでは、等価はインスタンスに基づいています。 2つの別々のインスタンスは決して等しくありません。独自のEqualsメソッドを提供することによってのみ変更できます。

+1

でも 'GetHashCode()'を実装したいと思います。 –

0

いいえ、彼らはキーとして使用されているとあなたがオブジェクト自体のインスタンス上で基本等価にしたくない場合にのみDictionary<TKey, TValue>

2

には型制約はありません。全く同じインスタンスへの参照を同等にする場合は、何もする必要はありませんが、キーとして型を使用していて、同等のインスタンスを等価と見なしたい場合は、クラスにEquals()およびGetHashCode()

カスタムタイプが値として格納され、キーとして使用されていないされている場合、これは当然のことながら、必要ありません。たとえば、この場合、MyTypeはEquals()またはGetHashCode()をオーバーライドする必要はありません。これは値としてのみ使用され、ストレージキーとしては使用されないためです。しかし、この場合

Dictionary<string, MyType> x; 

Dictionary<MyType, string> x; 

カスタムタイプはキーであり、したがってそれはEquals()GetHashCode()をオーバーライドする必要があります。 GetHashCode()は、ハッシュする場所を決定するために使用され、Equals()は、ハッシュコード(特に)の衝突を解決するために使用されます。

あなたにも多くのLINQクエリを扱うときに同じ2つのメソッドをオーバーライドする必要があると思います。また、スタンドアロンのIEqualityComparerをクラスから離して提供し、2つのインスタンスが同等かどうかを判断することもできます。

+0

しかし、参照の等価性が望ましい動作であれば、その型はこれらのメソッドをオーバーライドしてはならず、OPは参照の等価性*が*望ましい動作であることを示しているようです。 – phoog

+0

@phoog:良い質問、彼の声明「私の場合、彼らは同じインスタンスでなければ平等ではありません」私にとっては、「これは何をしているのか」、「これは私が望むもの」私は自分の答えをどちらかの方法で反映するように更新しました。 –

0

EqualityComparer.Default<T>プロパティを参照してください。これは、辞書にそれを与えないと辞書が等価比較子を取得する方法です。

これは、例えばT.

の種類&機能に基づいて等値比較を返すTがIEquatableを拡張する場合、EqualityComparer.DefaultはIEquatableインターフェイスを使用する等値比較のインスタンスを返します。それ以外の場合は、Object.Equalsメソッドを使用する等価比較インスタンスが返されます。

Object.Equalsメソッドは、参照型の既定では、カスタム比較でオーバーライドするまで参照参照(Object.ReferenceEquals)を使用します。

Object.Equalsメソッドは、デフォルトで値型として使用され、リフレクションを使用して構造体のフィールドを同等かどうか比較します。反射が遅いので、値の型でEqualsをオーバーライドすることを常にお勧めします。

*生のビットを比較するblittable値の型でない限り、*。