4

自分が書いたクラスをキーのタイプとして使用する必要がありますDictionary

のデフォルトコンストラクタについてMSDNのドキュメントを読みましたDictionary

Dictionary<TKey, TValue>キーが等しいかどうかを判断するには、等式の実装が必要です。このコンストラクターは、デフォルトのジェネリック等式比較子を使用しますEqualityComparer<T>.Default。type がジェネリックインターフェイスをTKey実装している場合System.IEquatable<T>、デフォルトの等式比較プログラムはその実装を使用します。IEqualityComparer<T>または、比較パラメーターを受け入れるコンストラクターを使用して、ジェネリックインターフェイスの実装を指定することもできます。

これにより、私がしなければならないのは、キーのクラスを実装することだけだと思います。System.IEquatable<T>

しかし、私は方法System.IEquatable<T>がないことに非常に驚いていHashCode()ます。

では、この方法で作成された辞書はハッシュコードを使用しますか?はいの場合、それはどこから来ていますか?そうでなければ、私の辞書は一定のコストのアクセス操作を持ちますか(ハッシュコードなしでは達成できないと思います)

4

4 に答える 4

4

ただし、System.IEquatableにHashCode()メソッドがないことに非常に驚いています。

System.Object(実装クラスが暗黙的に継承する)がすでにメソッドGetHashCodeSystem.IEquatable<T>を提供しているため、HashCodeメソッドを使用するのは冗長です。

于 2012-11-14T19:18:33.137 に答える
1

はい、辞書はハッシュコードを使用します。辞書は実際にはカバーの下にあるハッシュマップです。

GetHashCode使用するハッシュコードの実装は、キーに実装されているものです。実装を自分で定義しない場合、ハッシュコードは、参照型の参照と、値型(構造体)の個々のフィールドに基づきます。独自のクラスを辞書のキーとして使用する場合は、を実装することをお勧めしますGetHashCode

を実装するときは、の実装と一致するようにオブジェクトをオーバーライドIEquatable<T>する必要があります。それがインターフェースにない理由は、すべてのクラスが派生するですでに定義されているため、インターフェースにそれを置いても違いはありません。EqualsGetHashCodeIEquatable<T>GetHashCodeobject

実装に失敗して実装GetHashCodeと一致するIEquatable<T>場合、キーを辞書に入れても、ハッシュコードが一致しないため、キーを再度取得できないという問題が発生する可能性があります。辞書がキーを検索するとき、最初GetHashCodeにそのキーを呼び出します。これから、辞書はbucketキーが含まれるべき内部を導き出します。次に、その特定のバケット内のすべてのキーEqualsを調べて、正しいキーを見つけるために呼び出します。

于 2012-11-14T19:15:31.997 に答える
1

引き続きオーバーライドさobject.GetHashCode()れたメソッドを使用してハッシュコードを取得します。別個のIEquatable<T>インターフェースがある理由(つまり、デフォルトEqualityComparer<T>が常にオーバーライドされたobject.Equals()メソッドを呼び出して2つのオブジェクトを比較するわけではない理由)は、パフォーマンス上の理由からです-引数をobject.Equals()取るobjectため、実装はそれをターゲットタイプにキャストする必要があります意味のある比較を実行します(値の型もボックス化およびボックス化解除する必要があります)。一方、toの引数IEquatable<T>.Equals()はすでにタイプTです。このパフォーマンスの考慮事項は、引数をとらないためメソッドには適用されません。したがって、インターフェイスGetHashCode()に存在する理由はありません。IEquatable<T>

于 2012-11-14T19:20:19.447 に答える
0

辞書(HashSetおよびKeyedCollections)はすべてHashBuckets(速度のため)を使用します。
HashBucketsは、Int32であるGetHashCodeを使用します。

オブジェクトが等しくない場合、それらは異なるGetHashCodeを持っている必要があります。
ただし、等しくない2つのオブジェクトは、同じGetHashCodeを持つ可能性があります。

GetHashCodeが同じである場合、タイブレーカーはEqualsです。
GetHashCodeの比較はより高速です-タイブレーカーを避けたいと思います。

優れた(一意の)GetHashCodeが必要です。
オブジェクトがデータベースからのものであり、テーブルにキーがあり、そのキーがInt32(またはそれ以下)である場合は、それを使用して完全なハッシュコードを作成します。

オブジェクトに自然キーがない場合は、システムGetHashCodeを使用できます。
ただし、自然キーがある場合はそれを使用してください。

すべてのオブジェクトはオブジェクト オブジェクトクラス
を実装 しますクラスがGetHashCodeを上書きしない場合、それはオブジェクトから取得されます。

優れたGetHashCodeを生成しないため、TupleまたはKeyValuePairforKeyに対してアドバイスします。たくさんの衝突。

于 2012-11-14T19:24:30.187 に答える