3

まず、ここでGetHashCode説明するアルゴリズムを使用しています。ここで、次の(考案された)例を想像してください。

class Foo
{
    public Foo(int intValue, double doubleValue)
    {
        this.IntValue = intValue;
        this.DoubleValue = doubleValue;
    }

    public int IntValue { get; private set; }
    public double DoubleValue { get; private set; }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;

            hash = hash * 23 + IntValue.GetHashCode();
            hash = hash * 23 + DoubleValue.GetHashCode();
            return hash;
        }

    }
}

class DerivedFoo : Foo
{
    public DerivedFoo(int intValue, double doubleValue)
       : base(intValue, doubleValue)
    {

    }
}

各プロパティに同じ値のaFooとaがある場合DerivedFoo、それらは同じハッシュコードを持ちます。HashSet<Foo>つまり、Linqでこのメソッドを使用することも、使用することもできDistinct、2つのインスタンスは同じものとして扱われます。

私はおそらくの使用法を誤解しているだけですGetHashCodeが、これら2つのインスタンスは異なるハッシュコードを持っていると思います。これは無効な期待GetHashCodeですか、それとも計算でタイプを使用する必要がありますか?(またはDerivedClassオーバーライドする必要がありますGetHashCode)?

PSこのトピックに関連して、SOに関する質問がたくさんあることはわかっていますが、この質問に直接答える質問は見つかりませんでした。

4

2 に答える 2

6

GetHashCode()一意性を保証することは想定されていません(ただし、可能な限り一意である場合はパフォーマンスに役立ちます)。

の主なルールGetHashCode()は、同等のオブジェクトが同じハッシュコードを持つ必要があるということですが、それは、同等でないオブジェクトが同じハッシュコードを持つことができないという意味ではありません。

2つのオブジェクトが同じハッシュコードを持っている場合、Equals()メソッドが呼び出されて、それらが同じであるかどうかが確認されます。タイプが異なるため(もちろん、Equalsオーバーロードをどのようにコーディングしたかによって異なります)、それらは等しくなく、したがって問題ありません。

タイプごとに異なるハッシュコードアルゴリズムを使用している場合でも、常に衝突の可能性があるため、チェックEquals()必要です。

上記の例では、 fromのデフォルトの実装は参照の同等性チェック であるため、これを実装しないEquals()と、ハッシュコードに関係なくすべてのオブジェクトが区別されます。Equals()object

Equals()まだ行っていない場合は、タイプごとにオーバーライドして(必要にGetHashCode()応じて実装を継承することも、新しいものを使用することもできます)、比較対象オブジェクトのタイプがそれらが等しいと宣言する前に同じです。そして、次のように常に実装されていることを確認Equals()してください。GetHashCode()

  • あるオブジェクトは同じ結果になるEquals() 必要があります。GetHashCode()
  • 異なるオブジェクトは。であってはなりGetHashCode()ませEquals()
于 2011-09-08T14:27:35.000 に答える
1

2つのインスタンスは、異なるハッシュコードを持つ必要はありません。GetHashCodeの結果は、型内でも衝突が発生する可能性があるため、HashSetまたは他のフレームワーククラスでは想定されません。GetHashCodeは、アイテムを格納するハッシュテーブル内の場所を決定するために使用されます。HashSet内で衝突が発生した場合は、Equalsメソッドの結果にフォールバックして、一意の一致を判別します。つまり、GetHashCodeを実装する場合は常に、Equalsも実装する必要があります(タイプが一致することを確認してください)。同様に、Equalsを実装するときはいつでも、GetHashCodeも実装する必要があります。ここでEricLippertによる良い説明を参照してください。

于 2011-09-08T14:28:46.077 に答える