1

一見単純な問題に困惑しています。!=と比較している2つのオブジェクトがあります。

アプリケーションを実行すると、a!=bが真になります。ブレークポイントを設定してウォッチを実行すると、a.GetHashCode()== b.GetHashCode()がtrueになります。

これらの2つの(参照型)オブジェクトは別のアセンブリで定義されていますが、!=メソッドのオーバーライドが見つかりません(GetHashCodeはオーバーライドされていますが)。これについて別の説明はありますか?2つのオブジェクトのGetHashCodeが同じである可能性はありますが、オーバーライドされていない!=はtrueを返しますか?

ありがとう。

4

2 に答える 2

6

異なる2つのオブジェクトが同じコードを返す場合、それは「衝突」と呼ばれます。可能な整数値は約40億であり、[ここでのクラス名]の可能な値は40億を超えるため、衝突は避けられません。これが、ハッシュベースの構造(つまりDictionary)が完全に依存できない理由です。効果を上げるには、賢明な実装GetHashCodeも必要です。EqualsこのEquals方法は、これらの衝突を解決するために使用されるものです。

もちろん、クラスの作成者がハッシュコードを生成するための「契約」に違反したか、GetHashCodeまたはEquals何らかの方法で間違いを犯した可能性もあります。 これは、メソッドを作成するときに覚えておくべきガイドラインの1つのリストですGetHashCodeあなたがしなければならないことのかなり小さなセットと、それを効率的に機能させるために行うことができる別のセットがあることを忘れないでください。

return 0;実際には完全に受け入れ可能なGetHashCode実装です。すべてのルールに準拠しており、衝突を引き起こす可能性が100%しかないため、非常に非効率的であり、実際にそうするべきではありません。

于 2012-09-21T20:18:43.320 に答える
1

等しくない2つのオブジェクトが同じハッシュコードを持つことは完全に合法ですが、等しい2つのオブジェクトが異なるハッシュコードを持つことは無効です。

ディクショナリスタイルのコレクションクラスは、ハッシュコード値(キーとして指定されたオブジェクトから返されるGetHashCode値)を使用して、キーと値のペアをハッシュビンに入れます。キーのハッシュコード値が同じであるすべてのキー/値ペアは、同じハッシュビンに入ります。ハッシュコードの生成が効果的である場合、辞書内の空でない各ハッシュビンには、キーと値のペアが非常に少ない(できれば1つだけ)ことを意味します。

オブジェクトをキーとして指定してディクショナリのコンテンツにアクセスする場合、返される正しい値を見つけるための疑似ロジックは次のとおりです。

  1. リクエストでキーとして指定されたオブジェクトのハッシュコード値を取得します(GetHashCode())
  2. そのハッシュコードに空でないハッシュビンがある場合は、そのハッシュビン内のすべてのキー/値ペアのキーオブジェクトを反復処理します。ハッシュビン内のキーと値のペアごとに、キーオブジェクトEquals()がリクエストへのキーとして渡されたオブジェクトであるかどうかを確認します。その場合、そのキーと値のペアでValueオブジェクトを返します。

これにより、リストスタイルのコレクションでオブジェクトを検索する場合と比較して、辞書の検索が非常に効果的になります(ハッシュコードの分散が良好な場合)。

于 2012-09-21T21:02:24.110 に答える