アイテムがオブジェクトにキャストされるときにequalsが同じように機能しないのはなぜですか?

私が整数をキャストしてオブジェクトに浮かべてそれらを比較すると、平等は常に偽です。どうして?

        float f = 0.0f;
        int i = 0;
        Console.WriteLine(f.Equals(i));//true
        Console.WriteLine(i.Equals(f));//false
        Console.WriteLine(i == f);//true
        Console.WriteLine("----------------");
        object obf = f;
        object obi = i;
        Console.WriteLine(obf.Equals(obi));//false
        Console.WriteLine(obi.Equals(obf));//false
        Console.WriteLine(obi == obf);//false
        Console.WriteLine("----------------");

更新: これは同じタイプの場合ではありません

        int i1 = 1;
        int i2 = 1;
        object oi1 = i1;
        object oi2 = i2;
        Console.WriteLine(oi1.Equals(oi2));//true
        Console.WriteLine(oi2.Equals(oi1));//true
6

8 答え

float は別の float にのみ等しく、 int は別の int と同じです。 true を返す行は次のものだけです:

Console.WriteLine(f.Equals(i));
Console.WriteLine(i == f);

どちらの場合も、 i の値は float に暗黙的に変換されます。

Console.WriteLine(f.Equals((float) i));
Console.WriteLine((float) i == f);

これらの変換は、メソッドや演算子のオーバーロード解決に必要な通常の変換です。

残りの行には暗黙の変換が含まれていないので、2つの異なる型を比較しているので、 値で比較しても false すべての Equals 呼び出しの場合です)。そのため、ボックス化された int 値で Equals を使用すると true価値によって

この場合:

Console.WriteLine(obi == obf);

数値化された値を比較しようとしていません。ボックス化されたオブジェクトの参照を比較しています。 2つの異なる参照があるため、結果は false です。両方の値が int 型であっても結果は同じです。

10
追加された
@CharlesLambert:はい。 ILを見て、それが実行されているのを見るでしょう。
追加された 著者 Jon Skeet,
暗黙の変換はコンパイル時に処理されるのですか?
追加された 著者 Charles Lambert,

あなたのオブジェクトで == が期待どおりに機能しない理由について他の人がすでに説明しています。

編集に関して: Equals は仮想関数なので、 Int32.Equals(object) が呼び出されます。

objがInt32のインスタンスであり、このインスタンスの値と等しい場合、

true それ以外の場合は false

また、 obi.Equals(obf))がfalseを返す理由についても説明します。 obf はInt32のインスタンスではありません。

3
追加された

intをボクシングしてオブジェクトに浮かべているので、参照として比較されます。それらは同じオブジェクトへの参照ではないので、同じではありません。

See http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx

1
追加された

2つのオブジェクトを宣言すると、別のメモリ位置を参照します:

object obf = f;        //this simplified as new float(f)
object obi = i;        //this simplified as new int(i)

次のように試してみましょう。一方のオブジェクトが他方のオブジェクトを参照するようにします。

obf = obi;
Console.WriteLine(obf.Equals(obi));

MSDN, Object.Equals Method

Equalsのデフォルトの実装では、   参照型、および値型のビット単位の等価性があります。参照   等価とは、比較されるオブジェクト参照を意味します。   同じオブジェクト。ビット単位の等価性は、比較されるオブジェクトが   同じバイナリ表現です。

1
追加された

ボックスの値の型のときに何が起こるかについてもっと理解するために、Shivprasadはこれをここでは非常に簡潔に説明しています。

ボクシングとアンボクシング

値の型をオブジェクトにボクシングするので、参照の平等を実行しています。彼らは今あなたの例では異なるメモリ位置に存在するので、falseを返します。

1
追加された

Equals はオブジェクト参照のアドレスを比較し、2つの数値は異なる場所に格納されるためです。 2つの値の型を比較す​​ると、equalsはfloat、int、stringなどの型に対してオーバーライドされているため正しく動作します。

0
追加された

彼らは別のmemeory細胞に割り当てられているからです。 2つのオブジェクトは、それらが同じオブジェクトである場合のみです。 floatとintの部分では、実行時に値がチェックされるため、2つの変数をテストすると真となります。 それで全部です!

0
追加された

値の型をオブジェクトにキャストすると、実際にヒープに入れられ、その点の参照を比較します(= false)。 (簡体字)

0
追加された