13

この質問を読んだ後、「int」と「sbyte」の GetHashCode 関数が異なる値を生成するのはなぜですか? さらに掘り下げて、次の動作を見つけました。

sbyte i = 1;            
int j = 1;
object.Equals(i, j) //false (1)
object.Equals(j, i) //false (2) 
i.Equals(j) //false (3)
j.Equals(i) //true (4)
i == j //true (5)
j == i //true (6)
i.GetHashCode() == j.GetHashCode() //false (7)
  1. (3) と (4) の違いは、Equals が対称でなければならないという要件を破っています。
  2. (2) と (4) の違いは、次のMSDN 仕様と一貫性がありません。

    2 つのオブジェクトが同じオブジェクト参照を表さず、どちらも null でない場合、objA.Equals(objB) を呼び出して結果を返します。つまり、objA が Object.Equals(Object) メソッドをオーバーライドすると、このオーバーライドが呼び出されます。

  3. (3) と (5) の違いは、演算子 == が true を返すことを意味しますが、オブジェクトは Equals に関して等しくありません。
  4. (4)、(5)、(6)、(7) の違いは、2 つのオブジェクトが演算子 == と Equals に関して等しいことを意味しますが、ハッシュ コードは異なります。

私の意見では、このような一貫性のない動作がかなり基本的な .NET 型で観察される理由を誰かが説明できる場合、私は非常に興味があります。

4

1 に答える 1

15

あなたの問題は、 の暗黙的な変換を見逃したことですi.Equals(j)。過負荷に行きint.Equals(int)ます。ここでは と を比較iしています(int)jが、どちらも同じものです。に対しても同じ暗黙の変換が行われ==ます。

他の比較は、定義により異なるanintと aで機能します。引数は暗黙的に に変換できないため、オーバーロードに移動します。sbytej.Equals(i)int.Equals(object)sbyte

Equalsそれらに対して対称ですが、呼び出しコードはそうではありません。で暗黙の変換を抑制するとi.Equals((object)j)、 が返され、それが実際に対称falseであることを示します。Equals

于 2012-09-19T20:45:57.180 に答える