为什么长整数和小数之间的相等不交换?

哥斯达黎加

我在linqpad中运行以下代码:

    long x = long.MaxValue;
    decimal y = x;

    x.Dump();
    y.Dump();

    (x == y).Dump();
    (y == x).Dump();

    Object.Equals(x, y).Dump();
    Object.Equals(y, x).Dump();
    x.Equals(y).Dump();
    y.Equals(x).Dump();

它产生以下输出:

    9223372036854775807
    9223372036854775807
    True
    True
    False
    False
    False
    True

请注意最后两行:x.Equals(y)为false,但y.Equals(x)为true。因此,十进制认为自己等于具有相同值的long,但long并不认为自身等于具有相同值的十进制。

对这种行为有何解释?

更新:

我接受了李的回答。

我对此很好奇,并编写了这个小程序:

using System;
namespace TestConversion
{
  class Program
  {
    static void Main(string[] args)
    {
      long x = long.MaxValue;
      decimal y = x;

      Console.WriteLine(x);
      Console.WriteLine(y);

      Console.WriteLine(x == y);
      Console.WriteLine(y == x);

      Console.WriteLine(Object.Equals(x, y));
      Console.WriteLine(Object.Equals(y, x));
      Console.WriteLine(x.Equals(y));
      Console.WriteLine(y.Equals(x));
      Console.ReadKey();
    }
  }
}

然后我在IL中将其分解:

.method private hidebysig static void Main(string[] args) cil managed
{
  .entrypoint
  .maxstack 2
  .locals init (
    [0] int64 x,
    [1] valuetype [mscorlib]System.Decimal y)
  L_0000: nop 
  L_0001: ldc.i8 9223372036854775807
  L_000a: stloc.0 
  L_000b: ldloc.0 
  L_000c: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int64)
  L_0011: stloc.1 
  L_0012: ldloc.0 
  L_0013: call void [mscorlib]System.Console::WriteLine(int64)
  L_0018: nop 
  L_0019: ldloc.1 
  L_001a: call void [mscorlib]System.Console::WriteLine(valuetype [mscorlib]System.Decimal)
  L_001f: nop 
  L_0020: ldloc.0 
  L_0021: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int64)
  L_0026: ldloc.1 
  L_0027: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)
  L_002c: call void [mscorlib]System.Console::WriteLine(bool)
  L_0031: nop 
  L_0032: ldloc.1 
  L_0033: ldloc.0 
  L_0034: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int64)
  L_0039: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)
  L_003e: call void [mscorlib]System.Console::WriteLine(bool)
  L_0043: nop 
  L_0044: ldloc.0 
  L_0045: box int64
  L_004a: ldloc.1 
  L_004b: box [mscorlib]System.Decimal
  L_0050: call bool [mscorlib]System.Object::Equals(object, object)
  L_0055: call void [mscorlib]System.Console::WriteLine(bool)
  L_005a: nop 
  L_005b: ldloc.1 
  L_005c: box [mscorlib]System.Decimal
  L_0061: ldloc.0 
  L_0062: box int64
  L_0067: call bool [mscorlib]System.Object::Equals(object, object)
  L_006c: call void [mscorlib]System.Console::WriteLine(bool)
  L_0071: nop 
  L_0072: ldloca.s x
  L_0074: ldloc.1 
  L_0075: box [mscorlib]System.Decimal
  L_007a: call instance bool [mscorlib]System.Int64::Equals(object)
  L_007f: call void [mscorlib]System.Console::WriteLine(bool)
  L_0084: nop 
  L_0085: ldloca.s y
  L_0087: ldloc.0 
  L_0088: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int64)
  L_008d: call instance bool [mscorlib]System.Decimal::Equals(valuetype [mscorlib]System.Decimal)
  L_0092: call void [mscorlib]System.Console::WriteLine(bool)
  L_0097: nop 
  L_0098: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  L_009d: pop 
  L_009e: ret 
}

您确实可以看到long值已转换为十进制。

谢谢你们!

背风处

发生这种情况是因为

y.Equals(x);

decimal.Equals(decimal)过载被调用,因为有一个隐式转换之间longdecimal结果,比较返回true。

但是,由于没有从decimal到的隐式转换long

x.Equals(y)

调用long.Equals(object)将导致y装箱,并且比较false不能返回到很长的时间,比较会返回

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么系统不交换?

为什么不交换数组索引?

为什么这不交换LinkedList的相邻对?

为什么我的类的 swap 方法不交换字符串中的选定项?

为什么 C 中的这个字符串交换函数不交换字符串?

在A和B之间交换元素以获得总和相等

为什么在CPU和GPU内存之间的数据交换这么慢?

为什么不交替匹配更长的令牌?

为什么生成的程序集在内联时按引用返回和复制之间不相等?

在计算机和交换机之间连接时,为什么5类交叉电缆可以工作?

为什么我会收到警告:指针和整数之间的比较?

对于负整数,为什么C和Ruby之间的模运算符(%)的行为不同?

为什么字符串和整数之间的+运算符充当substr

BLE GATT:为什么在整数类型中存储小数?

为什么Oracle不显示小数的整数部分

为什么hashcode()返回一个整数而不是长整数?

Ubuntu 16.04 从不交换

JavaScript为什么认为354224848179262000000和354224848179261915075是相等的?

为什么Thread和Task的逻辑结束时间相等?

为什么arange和linspace无法产生相等的对象?

为什么我的MySQL实例认为“'ī”和“ i”是相等的字符?

为什么 == 和 === 相等似乎对 UIView 类起作用?

为什么对设备和交换链使用相同的IDXGIFactory

为什么我的PCA不变于旋转和轴交换?

为什么交换方程的 LHS 和 RHS 会产生错误?

为什么SGI STL不使用复制和交换习惯?

JAXB整数和长解析

交换链表中的节点而不交换数据

std :: atomic_store和std :: atomic_exchange不交换