代码之家  ›  专栏  ›  技术社区  ›  Jose

两个相等的.NET对象并不表示它们相等

  •  14
  • Jose  · 技术社区  · 16 年前

    我有以下代码:

    object val1 = 1;
    object val2 = 1;
    
    bool result1 = (val1 == val2);//Equals false
    bool result2 = val1.Equals(val2); //Equals true
    

    怎么回事?只有使用.Equals()方法才能解决这个问题吗?

    7 回复  |  直到 10 年前
        1
  •  33
  •   Mark Byers    16 年前

    接线员 == 是静态的,而不是虚拟的,因此行为由静态类型而不是运行时类型决定。这个 违约 实施 == 在引用类型的对象上比较引用(尽管类型可以实现不同的行为,例如 string ). 你有两个不同的对象,它们没有相同的引用,所以 ==

    value1 具有运行时类型 Int32 Int32.Equals . 从.NET Reflector可以看到,它的实现如下所示:

    public override bool Equals(object obj)
    {
        return ((obj is int) && (this == ((int) obj)));
    }
    

    换句话说,它检查参数是否为 int ,如果是,则将其强制转换并使用 == 内景 . 这与 价值观

    另一种方法是将对象投射到 内景 Int32.Equals 做。

        2
  •  10
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    对。 == Equals 比较内容的位置。

        3
  •  2
  •   scy    16 年前

    == 检查两个对象是否匹配 . 他们不是。它们表示相同的数字,但存储在内存中的不同位置。

    就像比较两个苹果。两者都是 苹果

        4
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    这是因为当您将它们转换为对象时,它们被“转换”为int值的引用。而这两个参照物并不相等。 但是equals比较引用的值而不是引用。

        5
  •  0
  •   CaffGeek    16 年前

    object 但是对于自定义类,可以重写==和!=运算符,可能应该实现 IEqualityComparer<T> 接口

    public static bool operator ==(MyType left, MyType right)
    {
        //code here, don't forget about NULLS when writing comparison code!!!
    }
    
    public static bool operator !=(MyType left, MyType right)
    {
        return !(left == right);
    }
    
    public bool Equals(MyType x, MyType y)
    {
        return (x == y);
    }
    
    public int GetHashCode(MyType obj)
    {
        return base.GetHashCode();
    }
    
        6
  •  0
  •   Daniel Moura    16 年前

    val1 == val1; //Equals true
    

    正如tc所指出的,你可以使一个操作符过载。

    public static bool operator ==(Object a, Object b)
    

    这样操作员的行为 == 将是此方法定义的。

    != 当你超载时 == .

        7
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    这个 CIL 对于您的代码框,输入两个整数并比较装箱(==)产生的两个对象。这个比较是参考的。

      .locals init ([0] object val1,
               [1] object val2,
               [2] bool result1,
               [3] bool result2)
      IL_0000:  nop
      IL_0001:  ldc.i4.1
      IL_0002:  box        [mscorlib]System.Int32
      IL_0007:  stloc.0
      IL_0008:  ldc.i4.1
      IL_0009:  box        [mscorlib]System.Int32
      IL_000e:  stloc.1
      IL_000f:  ldloc.0
      IL_0010:  ldloc.1
      IL_0011:  ceq
      IL_0013:  stloc.2
      IL_0014:  ldloc.0
      IL_0015:  ldloc.1
      IL_0016:  callvirt   instance bool [mscorlib]System.Object::Equals(object)
      IL_001b:  stloc.3
    

    为了这个。等于它所召唤的Object.Equals,调用Int32.Equals(对象上的虚拟方法调用):

    public override bool Equals(object obj)
    {
        return ((obj is int) && (this == ((int) obj)));
    }
    

    这将强制转换为int并将值作为整数进行比较,这是一种值类型比较。