2011-04-21 5 views
15

静的メソッドObject.Equals(Object, Object)は、参照型の参照の等価性と値の型のビットの等価性をサポートしています。比較される値の等しいオブジェクトは、異なるバイナリ表現を持っていても同じ値を持ちます。 i1b1は異なるタイプのものであるので私はObject.Equals(Object、Object)がビットの等価性をサポートしており、値の等価性を持たないことを確認しました

例えば、それらは、同じバイナリ表現を持っていないので、Object.Equals(Object, Object)戻るfalsed1d2を比較するとき

 int i1 = 100; 
     byte b1 = 100; 
     Console.WriteLine(Object.Equals(i1, b1));//false 

Object.Equals(Object, Object)はまた、以降(falseを返すべきです2つの変数は同じ値の異なるバイナリ表現を持っています)、代わりにtrueを返します。これは、値の等しいを使用してそれらを比較することを示唆しています。

 decimal d1 = 1.10M; 
     decimal d2 = 1.100M; 
     Console.WriteLine(Object.Equals(d1, d2)); //true 

d2を比較すると、Object.Equals(Object, Object)が返されます。

http://msdn.microsoft.com/en-us/library/bsc2ak47.aspxから:

例えば、数字 1.10と1.1000を表す2進 オブジェクトを検討してください。 異なる後続ゼロ数を考慮して、異なるバイナリ 表現を持つため、Decimalオブジェクトはビット単位の等価を持ちません。

ありがとうMSDNから

+0

これは奇妙なバグだとわかりました –

答えて

1

:派生型が値の平等を実現するためのEqualsメソッドをオーバーライドする可能性があることを

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

注意。値の等しいことは、比較されたオブジェクトが同じ値であるが異なるバイナリ表現を持つことを意味します。

Decimalは、メタデータに見られるように、Equalsオーバーライドを確実に持ちます。

+0

そのページは静的なEqualsメソッド用です。 –

+1

静的なEqualsメソッドは、もう1つを呼び出します。 (両方のオブジェクトが存在し、参照等価でない場合) – Random832

+0

私が知る限り、Int32.Equals、Byte.Equals、Decimal.Equals(Object)は値の等しいものを使用しませんか? – user702769

1

Object.Equals(Object objA, Object objB)最初にクイックリファレンスチェック(objA == objB)を実行します。それが失敗すると、値が等しくなるようにDecimalがオーバーライドする仮想Object.Equals(Object obj)を呼び出そうとします。

+0

私が知る限り、Int32.Equals、Byte.Equals、Decimal.Equals(Object)は値の等しいものを使用しませんか? – user702769

5

リフレクターのようなツールを使って、Object.Equals(Object、Object)のソースを見ることができます。

は、ここではObject.equalsのソースコード(オブジェクト、オブジェクト)です:

public static bool Equals(object objA, object objB) 
{ 
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); 
} 

はのは句を調べてみましょう:

(objA == objB):これは、これら二つのオブジェクトかどうかをチェックし、オブジェクトの等価演算子であります同じオブジェクトを参照してください。この節は、このケースではfalseです。

(objA != null) && (objB != null)これは私たちの場合に当てはまります。

objA.Equals(objB):これは真(Decimal.Equalsにそれを委譲(オブジェクト))である

我々は||演算子のRHS上のすべてのtrueを持っているので、文全体がtrueに評価されます。

+0

Int32.Equals(Object obj)は、objがInt32のインスタンスであり、このインスタンスの値と等しい場合にtrueを返します。 objの型がbyteの場合、Falseを返します。 Int32.Equals(Object)がビット単位の比較を使用しているということではありませんか?それ以外の場合、objはint型ではなくbyte型なので、なぜfalseを返しますか? – user702769

+1

タイプをチェックする可能性があります。 objがInt32のインスタンスでない場合、falseを返します。 – ICR

+0

チェックタイプです。ここにInt32があります。等価(オブジェクトObj)、逆コンパイル: 'public override bool Equals(オブジェクトobj) { if(!(objがint)) falseを返します。 else これを返す==(int)obj; } ' – MCattle

1

どうやら、ビット単位の等価性は意味をなさないので、決して正しくありません。どのようなビット形式で保存されていても、実際のビジネス価値を気にしません。

ビジネスまたは科学目的の場合、1.10と1.100は同じです。ビット単位の比較は字句比較を意味しますが、これは間違っています。 「1.10」と「1.100」は、それらが不正確な語順を表すので、異なる。

実際のビットを比較する場合は、実際のビットシーケンスを与えるBitConverter.GetBytesを使用する必要があります。

Array.Compare( 
    BitConverter.GetBytes((decimal)1.10), 
    BitConverter.GetBytes((decimal)1.100)) 

Array.Compareメソッドがあるかどうかわかりませんが、作成することはできますが、ポイントを取得してもらいたいです。

+3

キャストの代わりに' 1.10m'を書いてください。 – svick

+0

'Equals(Object)'の型の振る舞いが他の等しい過負荷や '=='の振る舞いと一致しないケースがたくさんあります。私は 'Equals(Object)'が他のものよりも厳密な等式を表現すべきであることを示唆しています: '' X''''は '' Y''''に代わるものと考えるべきです。 '1.0m.Equals(1.00m)'が真であっても、 '1.0m.Equals(1.00m)'が真であるとしても、 '1.0m.Equals(1.00m)'はfalseでなければならないと思います。 '1.0m.Equals((Object)1)'はfalseですが、 '1.0m.Equals(1)'は真です。 – supercat

7

Object.Equalsは、(ビット単位ではなく)値の等価性を実装すべきです(SHOULD)。

Decimalの場合、両方のオブジェクトは同じ型で値は等しいので、結果はtrueです。

バイトの大文字と小文字の区別では、オブジェクトのタイプが異なるため、結果は偽です。

+0

»int、バイトの場合、オブジェクトの型が異なるため、結果はfalseです。 int32.Equals(Object obj)は、objがInt32のインスタンスであり、このインスタンスの値と等しい場合にtrueを返します。 objの型がbyte型の場合、Falseを返します。つまり、Int32.Equals(Object)はビット単位の比較を使用していますか?それ以外の場合、objはint型ではなくbyte型なので、なぜfalseを返しますか? – user702769

+2

Object.Equals(x)のすべてのオーバーライドは、xが正しい型でない場合はfalseを返します。通常、メソッドの最初のステートメントは "if(!(xはtypeof(...)がfalseを返す)"または何らかのバリアントを返します。 –

+0

同じ値であるが異なる型のものが決定された理由は、等しいか? – user702769

9

Decimalは値型であり、Equalsメソッドは実際にReflectionを使用してすべてのフィールドを比較します。詳細については、MSDNを参照してください。

ValueType.Equals Method

最後に、MSDNからあなたのスコープが不完全です。ここでは、次のとおりです。たとえば

、数字 1.10と1.1000を表す2進 オブジェクトを検討してください。 異なる後続ゼロ数を考慮して、異なるバイナリ 表現を持つため、Decimalオブジェクトはビット単位の等価を持ちません。 ただし、末尾の のゼロは重要でないため、数値が1.10と の1.1000は比較目的で等しいと見なされるため、オブジェクトの値は です。

関連する問題