2011-04-21 31 views
15

静态方法Object.Equals(Object, Object)支持引用类型的引用相等,以及值类型按位相等,其中比较的对象具有相同的二进制表示,而值比较对象具有相同的值,即使它们具有不同的二进制表示。我认为Object.Equals(Object,Object)支持按位相等且不等于值

例如,由于i1b1是不同类型的,他们不具有相同的二进制表示,因此Object.Equals(Object, Object)回报false

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

Object.Equals(Object, Object)也应该返回false比较d1d2(因为时这两个变量具有相同值的不同二进制表示),但它返回true,这表明它使用值相等来比较它们:

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

不应该Object.Equals(Object, Object)在比较d1d2时返回False?

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

例如,考虑到代表数字 1.10和1.1000两个小数 对象。小数对象不具有按位相等性,因为它们具有不同的二进制 表示,以解释不同数量的尾随零。

感谢名单

+0

这是一个奇怪的错误,你已经找到 – 2011-04-21 18:31:05

回答

1

从MSDN:

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

注意,派生类型可以重写Equals方法来实现价值的平等。值相等意味着比较对象具有相同的值但不同的二进制表示。

十进制绝对有一个等于重写,可以在元数据中看到。

+0

该页面是为静态Equals方法。 – 2011-04-21 18:35:05

+1

静态Equals方法调用另一个。 (只要两个对象存在并且不是引用相等) – Random832 2011-04-21 20:21:03

+0

就我所知,Int32.Equals,Byte.Equals和Decimal.Equals(Object)不使用值相等?! – user702769 2011-04-22 02:06:35

1

Object.Equals(Object objA, Object objB)首先进行快速参考检查(objA == objB)。如果失败,它会尝试调用虚拟Object.Equals(Object obj) Decimal覆盖以提供值相等。

+0

据我所知,Int32.Equals,Byte.Equals和Decimal.Equals(Object)不使用值相等?! – user702769 2011-04-22 02:07:30

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):这是检查是否这两个对象的对象相等运算符引用同一个对象。这个条款对我们的案件是错误的。

(objA != null) && (objB != null):这是我们的情况。

objA.Equals(objB):这是真实的(它委托给Decimal.Equals(对象))

我们已经上了||运营商的RHS所有true,所以整个语句评估为真。

+0

如果obj是Int32的实例并等于此实例的值,则Int32.Equals(Object obj)返回true。如果obj是byte类型,那么它返回False。这不就是说Int32.Equals(Object)使用按位比较吗?否则,为什么它仅仅因为obj是byte类型而不是int返回false? – user702769 2011-04-22 02:02:13

+1

它可能会检查类型。如果obj不是Int32的一个实例,它将返回false。 – ICR 2011-04-22 09:03:23

+0

它确实检查类型。这是Int32。等于(object obj),反编译: 'public override bool Equals(object obj) { if(!(obj is int)) return false; else return this ==(int)obj; }' – MCattle 2012-11-26 22:38:39

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 2011-04-21 18:48:47

+0

有很多情况下,Equals(Object)的类型行为与其他Equals重载的行为不匹配,也不匹配== ==。我会建议'Equals(Object)'应该代表一个比其他更严格的平等形式:应该是“应该'X'被认为是可以替代'Y''的。我认为,因为'1.0m'和'1.00m'的行为不同,'1.0m.Equals((Object)1.00m)'应该是false,即使'1.0m.Equals(1.00m)'为真,就像'1.0m.Equals((Object)1)'是错误的,但是'1.0m.Equals(1)'是真的。 – supercat 2012-12-18 23:35:33

7

Object.Equals应该实现值(而不是按位)相等。

在十进制的情况下,两个对象都是相同的类型和值是相等的,所以结果是真实的。

在int,byte大小写中,对象的类型不同,所以结果为false。

+0

»在int,byte大小写中,对象是不同类型的,因此结果为false。« 如果obj是Int32的实例并等于此实例的值,则Int32.Equals(Object obj)返回true。如果obj是byte类型的,那么它返回False。这并不意味着Int32.Equals(Object)使用按位比较?否则,为什么它仅仅因为obj是byte类型而不是int返回false? – user702769 2011-04-22 02:02:30

+2

几乎所有Object.Equals(x)的覆盖都会返回false,如果x不是正确的类型。通常,该方法的第一个陈述是“如果(!(x是typeof(...))返回false”或某种变体 – 2011-04-22 05:21:50

+0

任何想法为什么做出相同的值但不同类型的决定不应被视为等于? – user702769 2011-04-22 12:54:38

9

Decimal是一个值类型,Equals方法实际上使用Reflection来比较其所有字段。有关详细信息,请参阅MSDN:

ValueType.Equals Method

最后,从MSDN的范围是不完整的。那就是:

例如,考虑两个小数 对象代表数字 1.10和1.1000。小数对象不具有按位相等性,因为它们具有不同的二进制 表示,以解释不同数量的尾随零。 但是,对象的值为 ,因为数字1.10和 1.1000被认为是相等的,用于比较目的,因为尾随的 零不重要。

相关问题