2015-01-08 11 views
5

最初のステートメントがtrueと評価され、最後のステートメントがfalseと評価される理由はわかりませんが、長い日でした。オブジェクトにキャストしたときに0Lが0にならないのはなぜですか?

誰か説明できますか?ここ

0L.Equals(0) // true 
((object)0L).Equals(0L) // true 
((object)0L).Equals(0) // false 
+0

実際の問題は "0"が作成されていると思われ、キャストによってコンパイラは毎回異なるパターンを選択しています。 – BradleyDotNET

答えて

13

Object.Equalsは、まずオブジェクトが値型であるかどうかを比較します。この場合、どちらも異なります。

MSDN

現在のインスタンスは、値型、値の等価性 テスト等号(Object)メソッドである場合。値の等しいことは、次のことを意味します。2つの オブジェクトは同じ型です。次の例に示すように、値が12のByte オブジェクトの値が のInt32オブジェクトと等しくないのは、2つのオブジェクトのランタイムタイプが異なるためです。

+2

なぜこれが事実であるか理解するために、1つは起こっているボクシングを理解する必要があります。構造体には参照型のような継承はありません: 'object'は参照型と同じ意味の基本クラスではありません - 値型を' object'にキャストすると、実際に 'object'インスタンスの中に値がラップされます。参照型の場合、インスタンスを 'object'にキャストしても、' Int64'のオーバーライドされた 'Equals'が呼び出されます。 –

+0

OK、ボックス化されたInt64オブジェクトはInt64のEqualsメソッドを直接使用しません。私の意見は、それができればそれはより良いだろうということです、しかし、私はそれができない理由を得る。 – ken

+0

@ken:値の型はボックス化されていても参照型ではありません。ところで、もしそれらが等しくないようであっても 'Equals'ではなく' == 'と比較し、' false'を返すような振る舞いをします: '((object)0L)==((object )0L)// false'。ボクシングは新しいオブジェクトを作成し、 '=='は参照の平等を比較するからです。 –

0
((object)0L).Equals(0) 

あなたはint型の型にオブジェクトの種類を比較している(それは別の数値型であってもよいint型で私を引用いけない)

種類が異なっています。

+0

私はあなたの推論に同意しませんが、最初の例と異なるのはなぜですか? – BradleyDotNET

+0

'L'は' long(Int64) 'または' ulong'(サイズに依存します)を意味します。 – Tim

+0

@tim 0はどのような種類のものですか? – Buck3y3

0
0L.Equals(0) // true 

これは、パラメータとしてlongを受け入れるlong.Equals方法に解決されます。 intへのパラメータの実際の式。そのintは暗黙的にlongに変換されるので、long0が渡されます。これは他の値と同じです。

((object)0L).Equals(0L) // true 
((object)0L).Equals(0) // false 

ボクシングはここlonglong.Equals過負荷の使用を防ぎ、objectパラメータを受け入れるだけobject.Equalsオーバーロードを、残します。パラメータは両方ともとintを持つobject両方のスニペットであるため、どちらもボックス化されます。また、object.Equalsの実装では、パラメータのタイプをチェックし、異なるタイプのオブジェクトが等しくないとみなします。これらの2つのスニペットのうちの最初のスニペットが小切手を渡します。その時点で、値をチェックして均等であることを確認します。 2番目のスニペットがチェックに失敗し、結果はfalseになります。

関連する問題