当项目被投射到对象时,为什么等于不相同?

时间:2011-10-27 15:44:57

标签: c#

当我转换int并浮动到object并比较它们时,相等性始终为false。为什么呢?

        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

8 个答案:

答案 0 :(得分:10)

float仅等于另一个floatint仅等于另一个int。返回true的唯一行是这些:

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

在这两种情况下,都隐含地将i转换为float,因此它们等同于:

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

这些转换只是方法和运算符重载解析所需的正常转换。

其余部分都没有涉及隐式转换,因此他们正在比较两种不同的类型,即使 按值进行比较,也会得到false的结果(所有Equals次调用都是这种情况。这就是为什么在盒装Equals值上使用int 会返回true,因为它正在比较两个相同类型的值,按值

在这种情况下:

Console.WriteLine(obi == obf);

它甚至没有尝试比较数值 - 它正在比较盒装对象的引用。由于有两个不同的引用,结果为false - 即使两个值都是int类型也是如此。

答案 1 :(得分:3)

其他人已经解释了为什么==无法在您的对象上按预期工作。

关于您的编辑:oi1.Equals(oi2)有效,因为Equals是一个虚函数,因此调用Int32.Equals(object),其返回值定义如下:

  

true 如果obj是Int32的实例并且等于此实例的值;否则, false

这也解释了为什么obi.Equals(obf))返回false:obf不是Int32的实例。

答案 2 :(得分:1)

你正在装载int并浮动到一个对象,这意味着它们被比作作为引用。因为它们不是对同一个对象的引用,所以它们并不相同。

请参阅http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx

答案 3 :(得分:1)

当您声明了两个对象时,它们引用了不同的内存位置:

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的默认实现支持引用相等   引用类型和值类型的按位相等。参考   等于意味着被比较的对象引用引用   同一个对象。按位相等意味着被比较的对象具有   相同的二进制表示。

答案 4 :(得分:1)

为了更多地了解当您设置值类型时会发生什么,Shivprasad在这里非常简洁地描述了这一点:

Boxing and Unboxing

由于您正在将值类型装箱到对象,因此您现在正在执行引用相等性。由于它们现在位于示例中的不同内存位置,因此将返回false。

答案 5 :(得分:0)

当你将一个值类型转换为object时,它实际上被放入堆中并且==比较该点的引用,这将是false。 (简化的)

答案 6 :(得分:0)

因为Equals比较了对象引用的地址,并且这两个数字存储在不同的位置。如果比较两个值类型Equals的行为是正确的,因为它已被重写为float,int,string和其他类型。

答案 7 :(得分:0)

因为它们被分配到不同的记忆细胞。 2个对象=仅当它们是同一个对象时。 在float和int部分中,当您测试2个变量时,您会得到一个true,因为运行时会检查它们的值。 这就是全部!