私は、同等のタイプのほとんどのGetHashCode実装でXORベースの実装を使用します。私はseveral postsそれは私がGetHashCodeメソッドas suggested by Jon Skeet実施することを決定したように、最善の解決策ではない理由を説明読んだGetHashCodeでハッシュコードを計算するクラス
:
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
コードは、ほとんどの実装で同様である可能性が高いので、私はヘルパーを構築しようとしましたすべてのクラスのハッシュコードを計算します。それは簡単なことですが、GetHashCodeの主な制約の1つは、高速でなければならないことです。したがって、割り当てを含む実装はおそらく無意味です(たとえば、静的でないクラスの使用など)。
理想的には、このようなメソッドの呼び出しは次のようになります。
public override GetHashCode() => HashCodeCalculator.Calculate(X, Y, Z);
そして、すべてのロジック(未確認+素数+ヌルチェックを...)持っています。しかし、params
パラメータを使用すると、暗黙的に配列が作成されます。
ハッシュアルゴリズムを各クラスに複製するのが最善でしょうか?あるいは、以下のようなクラスが効率的ですか?
このように使用することができますpublic static class HashCalculator
{
private const int _seed = 5923;
private const int _multiplier = 7481;
public static int Add(object value) => Add(_seed, value);
public static int Add(int current, object value)
{
int valueHashCode = (value != null) ? value.GetHashCode() : 0;
unchecked
{
return (current * _multiplier) + valueHashCode;
}
}
}
:
public override int GetHashCode()
{
int result = HashCalculator.Add(Prop1);
result = HashCalculator.Add(result, Prop2);
return result;
}
私はこれについて考えたが、私は> 10個の特性が関与しているいくつかの例があります。ディクショナリのGetHashCode呼び出しごとに配列が作成されると、パフォーマンスに影響が出ます。 –
@ vc74実際に10個のプロパティがある十分な用途がある場合、ベンチマークを行ってアレイの割り当てが問題であると判断した場合は、最大10個(またはそれ以上)のオペランドになるオーバーロードを作成します。 – Servy
それについて考えると、それは実行可能な解決策だと思います。私はオーバーロードを重複させる考えは本当に好きではありませんが、これは他の方法がないコーナーケースになる可能性があります。 params IEnumerableは将来のソリューション(いつか実装されている場合)ですが、paramsと同じパフォーマンスの問題がある可能性があります。 –