-1

C#で統合/システムテストを作成するための小さなライブラリを実装しているときに発生した問題について、あなたの意見に興味があります。ライブラリは、テストオーサリングAPIとテストランタイムAPIの2つの部分で構成されています。テストライターは、オーサリングAPIを使用してテストプランのプロトタイプを作成します。ランタイムは、プロトタイプを取得し、プロトタイプのランタイム表現を作成して実行できます。

RuntimeTestPlanBuilderという名前のクラスをテストできるようにするには、ランタイムオブジェクトモデルクラス全体でEqualsメソッドをオーバーライドする必要がありました。これにより、GetHashCodeメソッドもオーバーライドする必要がある状況になりました。一部のランタイムオブジェクトモデルクラスにGetHashCodeを実装するのは簡単でした。ランタイムモデルの一部のクラスはGetHashCodeを実装するコンテナーであるため、それらは困難であり、不可能でさえありました(たとえば、ランタイムはコンテナーにアイテムを追加できるため、ハッシュコードはO(1)で計算できません)。

その結果、コンテナのユーザーがそれらをキーとして辞書に載せないようにする方法を考えました。私が選んだ解決策は、GetHashCodeメソッドをオーバーライドして、例外をスローすることです。実行時にのみ失敗するため、このソリューションには満足していません。さらに、なぜ.NetFrameworkの設計者がGetHashCodeメソッドをObjectクラスに配置することを選択したのか不思議に思います。コンテナを正当な辞書キーではないものとして適切にマークできないため、この決定が私の状況につながったと思います。

(.Net Frameworkの設計者にとって)より良い決定は、IHashableという名前のインターフェイスをEqualsとGetHashCodeの2つのメソッドで定義し、汎用ディクショナリのItemタイプに制約を付けてインターフェイスを適用することでした。このようにして、コンパイル時にキーがEqualsとGetHashCodeを実装するように強制できます。また、このインターフェースを実装していないクラスは辞書キーとして使用されることを想定していないことは容易に理解できます。

私の質問は次のとおりです。一部のクラスのインスタンスをディクショナリキーとして使用しないように指定するためのより良いソリューション(GetHashCodeから例外をスローしないソリューション)を提案できますか?

ありがとう

4

2 に答える 2

0

オブジェクトは5つのメソッドを実装することになっており、GetHashCodeはそのうちの1つです。
GetHashCodeの現在または将来の使用が辞書キーのみであるかどうかを確認することはできません。

唯一のルールは、2つの等しいオブジェクトが同じGetHashCodeを持っている必要があるということです。
ただし、同じGetHashCodeは、2つのオブジェクトが等しいことを意味するわけではありません。

GetHashCodeまたはコンテナ内のアイテム数に定数(1)を使用できます。
またはスキートからのこの回答を参照してください

is-it-possible-to-combine-hash-codes-for-private-members-to-generate-a-new-hash

于 2013-03-26T17:02:06.110 に答える
0

一般に、2つのオブジェクトは、それらが同等であり、常に同等である場合にのみ、同等であると報告する必要があります。したがって、可変コレクションを含む可変オブジェクトは、通常、互いに等しいと見なされるべきです。不変のコレクションは、メンバーGetHashCodeの値をキャッシュすることで効率的に実装できます。GetHashCode()構築はO(N)であり、ハッシュコードがオブジェクト構築で計算されるか、最初に要求されたときに計算されるかにかかわらず、それを計算するための合計ライフタイムコストは最大でO(N)になります。

どのクラスでもハッシュコードの実装が困難になる理由はありません。クラスが参照の等式を使用する場合、デフォルトGetHashCodeは完全です。可変の等式の定義を使用する場合はGetHashCode()、定数を返すだけでコントラクトに準拠できます。少数のインスタンスをディクショナリに入れようとするとパフォーマンスが低下する可能性がありますが、誰かがたとえば12個のアイテムを含むディクショナリを使用している可能性があり、そのサイズのディクショナリではパフォーマンスは問題ありません。

于 2013-11-19T00:07:33.557 に答える