Share via


moduloObjectHashcode MDA

moduloObjectHashcode マネージド デバッグ アシスタント (MDA) は、GetHashCode メソッドによって返されるハッシュ コードに対してモジュロ演算を実行するように、Object クラスの動作を変更します。 この MDA の既定の係数は 1 であり、これにより GetHashCode はすべてのオブジェクトに対して 0 を返すようになります。

現象

新しいバージョンの共通言語ランタイム (CLR) に移行すると、プログラムが正しく動作しなくなります。

  • プログラムは、Hashtable から正しくないオブジェクトを取得します。

  • Hashtable からの列挙の順序に、プログラムが動作しなくなる変更があります。

  • 以前は等しかった 2 つのオブジェクトが、等しくなくなっています。

  • 以前は等しくなかった 2 つのオブジェクトが、等しくなっています。

原因

Hashtable へのキーに対するクラスの Equals メソッドの実装は、GetHashCode メソッドの呼び出しの結果を比較することによりオブジェクトの等価性をテストするため、プログラムが Hashtable から正しくないオブジェクトを取得している可能性があります。 それぞれのフィールドの値が異なる場合であっても、2 つのオブジェクトのハッシュ コードが同じになる場合があるので、オブジェクトの等価性のテストにハッシュ コードを使うことはできません。 実際にはまれなことですが、ハッシュ コードの衝突が発生します。 このことによる Hashtable のルックアップへの影響としては、等しくない 2 つのキーが等しいものと見なされ、正しくないオブジェクトが Hashtable から返されます。 パフォーマンス上の理由から、GetHashCode の実装はランタイム バージョンによって変更される場合があり、あるバージョンでは発生しない競合が後のバージョンでは発生する可能性があります。 ハッシュ コードが競合するときのバグがコードにあるかどうかをテストするには、この MDA を有効にします。 この MDA を有効にすると、GetHashCode メソッドは 0 を返すようになり、結果としてすべてのハッシュ コードが競合します。 この MDA を有効にすることによるプログラムへの唯一の影響は、プログラムの実行が遅くなることです。

キー変更のハッシュ コードの計算に使われるアルゴリズムがランタイムのあるバージョンから別のバージョンに変更された場合、Hashtable からの列挙の順序が変わる可能性があります。 ハッシュ テーブルからのキーまたは値の列挙順序にプログラムが依存しているかどうかは、この MDA を有効にすることでテストできます。

解決方法

オブジェクト ID の代わりに、ハッシュ コードを使わないでください。 ハッシュ コードを比較しないように、Object.Equals メソッドのオーバーライドを実装します。

ハッシュ テーブル内のキーまたは値の列挙の順序への依存関係を作成しないでください。

ランタイムへの影響

この MDA を有効にすると、アプリケーションの速度が低下します。 この MDA は、返されたハッシュ コードを取得し、代わりに係数で除算したときの余りを返します。

出力

この MDA に出力はありません。

構成

modulus 属性では、ハッシュ コードで使う係数を指定します。 既定値は 1 です。

<mdaConfig>  
  <assistants>  
    <moduloObjectHashcode modulus="1" />  
  </assistants>  
</mdaConfig>  

関連項目