4

1 ~ 2 個の int、おそらく datetime または小さな文字列を含む ID クラス/構造体を使用しています。これらを辞書のキーとして使用します。

このような場合に GetHashCode をオーバーライドするにはどうすればよいでしょうか? 非常にシンプルですが、うまくいけばある程度パフォーマンスが向上します。

ありがとう

4

1 に答える 1

1

Essential C#をご覧ください。

GetHashCode()正しく上書きする方法の詳細な説明が含まれています。

本からの抜粋

ハッシュ コードの目的は、オブジェクトの値に対応する数値を生成することにより、ハッシュ テーブルのバランスを効率的にとることです。

  • 必須:等しいオブジェクトには等しいハッシュ コードが必要です (if a.Equals(b)、 then a.GetHashCode() == b.GetHashCode())
  • 必須: GetHashCode()オブジェクトのデータが変更された場合でも、特定のオブジェクトの存続期間中の の戻り値は一定 (同じ値) である必要があります。多くの場合、これを強制するためにメソッドの戻り値をキャッシュする必要があります。
  • 必須: GetHashCode()例外をスローしないでください。GetHashCode()常に正常に値を返す必要があります。
  • パフォーマンス:ハッシュ コードは可能な限り一意にする必要があります。ただし、ハッシュ コードは のみを返すintため、int が保持できるよりも多くの値を持つ可能性があるオブジェクト (事実上すべての型) のハッシュ コードには重複が必要です。(明らかな例は です。これは、が一意に識別できる値よりもlong多くの可能な値があるためです。)longint
  • パフォーマンス:可能なハッシュ コード値は、int. たとえば、ラテン語ベースの言語での文字列の分布が主に最初の 128 ASCII 文字に集中するという事実を考慮しないハッシュを作成すると、文字列値の分布が非常に不均一になり、強力なGetHashCode()アルゴリズムにはなりません。
  • パフォーマンス: パフォーマンス GetHashCode()のために最適化する必要があります。GetHashCode()一般にEquals()、ハッシュ コードが異なる場合に完全等号比較を短絡するために実装で使用されます。その結果、型がディクショナリ コレクションのキー型として使用されるときに頻繁に呼び出されます。
  • パフォーマンス: 2 つのオブジェクト間のわずかな違いが、ハッシュ コード値の大きな違いにつながるはずです。理想的には、オブジェクトの 1 ビットの違いによって、平均して約 16 ビットのハッシュ コードが変化します。これにより、ハッシュ値をどのように「バケット化」しても、ハッシュ テーブルのバランスが保たれます。
  • セキュリティ:攻撃者が特定のハッシュ コードを持つオブジェクトを作成することは困難です。攻撃は、すべてが同じ値にハッシュされる大量のデータでハッシュ テーブルをあふれさせることです。ハッシュ テーブルの実装は O(1) ではなく O(n) になり、サービス拒否攻撃が発生する可能性があります。

ここで既に述べたように、オーバーライドについていくつかの点を考慮する必要があり、Equals()これら 2 つの関数を実装する方法を示すコード例がいくつかあります。

したがって、これらの情報は出発点となるはずですが、本を購入して第 9 章 (少なくとも最初の 12 面) をすべて読んで、これら 2 つの重要な機能を正しく実装する方法に関するすべてのポイントを取得することをお勧めします。

于 2010-07-08T13:46:25.167 に答える