9

C#のクラス用に独自のGetHashCodeメソッドを作成するための最良の方法は何ですか?次のような単純なクラス(Equalsメソッドをオーバーライドする)があるとします。

class Test
{
   public string[] names;

   public double[] values;

   public override bool Equals(object obj)
   {
      return (obj is Test) && this.Equals((Test)obj);
   }

   public bool Equals(Test t)
   {
      return names.Equals(t.names) && values.Equals(t.values);
   }
}

GetHashCodeメソッドにデフォルトのコードを使用する必要がありますか?

public override int GetHashCode()
{
   return base.GetHashCode();
}

クラスの内容に基づいてメソッドを作成する必要がありますか?

public override int GetHashCode()
{
   return names.GetHashCode() + values.GetHashCode() ;
}

それとも私は何か他のことをすべきですか?

4

4 に答える 4

12

System.ArrayGetHashCodeまたはをオーバーライドしないEqualsため、参照の等式を使用します。したがって、それらを呼び出すべきではありません。

実装するには、この質問GetHashCodeを参照してください。

を実装するには、 extensionメソッドEqualsを使用します。SequenceEqual

編集:.Net 2.0では、次のように独自のバージョンを作成する必要がありますSequenceEqual

public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
    if (first == second) return true;
    if (first == null || second == null) return false;

    if (first.Count != second.Count) return false;

    for (int i = 0; i < first.Count; i++)
        if (!first[i].Equals(second[i]))
            return false;

    return true;
}

IEnumerable<T>の代わりに取るように書くことIList<T>もできますが、パラメーターのサイズが異なると早期に終了できないため、多少遅くなります。

于 2009-07-22T15:36:22.333 に答える
2

.GetHashCode()のオーバーライドを.Equals()と歩調を合わせて維持することが非常に重要です。

基本的に、GetHashCodeの3つのルール( MSDN object.GetHashCode()から)の最初のルールに違反しないように、同じフィールドを考慮していることを確認する必要があります。

2つのオブジェクトが等しいと比較される場合、各オブジェクトのGetHashCodeメソッドは同じ値を返す必要があります。ただし、2つのオブジェクトが同等であると比較されない場合、2つのオブジェクトのGetHashCodeメソッドは異なる値を返す必要はありません。

つまり、.Equalsが2つのインスタンスが等しいと見なすたびに、それらにも同じ.GetHashCode()があることを確認する必要があります。

ここで他の誰かが述べたように、この質問は良い実装を詳述しています。興味のある方のために、昨年初めにハッシュコードの調査に関するブログ記事をいくつか書きました。あなたはここで私のとりとめのないものを見つけることができます(私がこの主題について書いた最初のブログエントリ)

于 2009-07-22T15:46:29.163 に答える
1

ここで問題についての良い議論があり、最新のアップデートは、 SharpArchitectureによって提供されるBaseObject抽象クラスを参照しています。

もっとアドホックなものが必要な場合は、ReSharperがEquals()およびGetHashCode()用に生成するコードで問題ないことがわかりました。

于 2009-07-22T16:29:14.953 に答える
1

dotnetcore 2.1以降を使用する場合は、HashCode構造体のCombileメソッドをすべてのプロパティに使用でき、非常に使いやすく効率的です。

于 2019-11-15T14:18:18.460 に答える