10

こんにちは私は6つの文字列プロパティを持つクラスを持っています。一意のオブジェクトは、これらのフィールドの少なくとも1つに対して異なる値を持ちます

IEqualityComparerのGetHashCode関数を実装するために、6つのプロパティすべてを連結し、結果の文字列に対してGetHashCodeを呼び出します。

私は次の疑問を持っていました:

  1. 一意の値でGetHashcodeを呼び出す必要がありますか?
  2. 6つのプロパティの連結操作により、比較が遅くなりますか?
  3. 他のアプローチを使用する必要がありますか?
4

4 に答える 4

4

文字列フィールドの名前がafで、nullでないことがわかっている場合、これはGetHashCode()に対するReSharperの提案です。

public override int GetHashCode() {
  unchecked {
    int result=a.GetHashCode();
    result=(result*397)^b.GetHashCode();
    result=(result*397)^c.GetHashCode();
    result=(result*397)^d.GetHashCode();
    result=(result*397)^e.GetHashCode();
    result=(result*397)^f.GetHashCode();
    return result;
  }
}
于 2011-09-05T14:30:47.680 に答える
3

GetHashCode()は、それらのオブジェクトでEquals()を呼び出すと、trueを返すすべてのオブジェクトに対して同じハッシュコードを返す必要があります。これは、たとえば、フィールド値が何であるかに関係なく、ハッシュコードとしてゼロを返すことができることを意味します。ただし、ハッシュテーブルなどのデータ構造に格納すると、オブジェクトが非常に非効率になります。

文字列を組み合わせるのは1つのオプションですが、たとえば、ハッシュコード用に2つの文字列だけを組み合わせることができることに注意してください(すべての文字列をequalsで比較します!)。

結合された文字列に対して単一のハッシュを計算するのではなく、6つの別々の文字列のハッシュを結合することもできます。たとえば、 クイックハッシュコードとシンプルハッシュコードの組み合わせを参照してください。

これが文字列を連結するよりも大幅に高速になるかどうかはわかりません。

于 2011-09-05T14:13:03.460 に答える
3

GetHashCode「等しくない」オブジェクトに対して等しくない値を返す必要はありません。等しいオブジェクトに対して等しい値を返す必要があるだけです(オブジェクトの存続期間中も同じ値を返す必要があります)。

この意味は:

  1. 2つのオブジェクトがと等しいと比較される場合Equals、それらGetHashCodeは同じ値を返す必要があります。
  2. 6つの文字列プロパティの一部が厳密に読み取り専用でない場合、それらはGetHashCode実装に参加できません。

両方の点を同時に満たすことができない場合は、他の何かがバグの扉を開いたままにするため、設計を再評価する必要があります。

GetHashCode最後に、6つの文字列のそれぞれを呼び出しGetHashCode、ビット単位の演算を使用して6つの結果すべてを1つの値に統合することで、おそらく高速化できます。

于 2011-09-05T14:14:28.387 に答える
0

次の動作を使用できます。

http://moh-abed.com/2011/07/13/entities-and-value-objects/

于 2011-09-05T20:20:21.633 に答える