繁体   English   中英

我认为Object.Equals(Object,Object)支持按位相等而不是值相等

[英]I thought Object.Equals(Object, Object) support bitwise equality and not value equality

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

例如,由于i1b1属于不同类型,因此它们没有相同的二进制表示,因此Object.Equals(Object, Object)返回false

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

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

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

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

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

例如,考虑两个表示数字1.10和1.1000的Decimal对象。 Decimal对象没有按位相等,因为它们具有不同的二进制表示以说明不同数量的尾随零。

感谢名单

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

ValueType.Equals方法

最后,MSDN的范围不完整。 这里是:

例如,考虑两个表示数字1.10和1.1000的Decimal对象。 Decimal对象没有按位相等,因为它们具有不同的二进制表示以说明不同数量的尾随零。 但是,对象具有值相等性,因为对于比较目的,数字1.10和1.1000被认为是相等的,因为尾随零是无关紧要的。

Object.Equals应该实现值(非按位)相等。

在Decimal情况下,两个对象的类型相同且值相等,因此结果为true。

在int,byte的情况下,对象的类型不同,因此结果为false。

您可以使用像reflector这样的工具查看Object.Equals(Object,Object)的来源。

这是Object.Equals(Object,Object)的源代码:

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(Object))

我们在||的RHS上都是true 运算符,因此整个语句的计算结果为true。

来自MSDN:

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

请注意,派生类型可能会覆盖Equals方法以实现值相等。 值相等意味着比较的对象具有相同的值但具有不同的二进制表示。

Decimal肯定有一个Equals覆盖,可以在元数据中看到。

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

没有办法,按位相等没有意义,它永远不会正确。 无论以哪种按位格式存储,我们都不在乎我们关心实际的商业价值。

出于商业或科学目的,1.10和1.100是相同的。 按位比较意味着词法比较,这是错误的。 “1.10”与“1.100”不同,因为它们表示不正确的词汇序列。

如果要比较实际位,则应使用BitConverter.GetBytes,它将为您提供实际的位序列。

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

我不知道是否有一个Array.Compare方法,但你可以创建一个,希望你明白这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM