Two .NET objects that are equal don't say they are

后端 未结 7 1220
故里飘歌
故里飘歌 2020-12-06 05:09

I have the following code:

object val1 = 1;
object val2 = 1;

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


        
相关标签:
7条回答
  • 2020-12-06 05:48

    Yes. == checks for reference equality. Use Equals where you want to compare content.

    You might be wondering why this is so with objects. When you set an integer (value type) to an object variable, an operation called boxing happens. This operation wraps the value type into an object and puts it on the heap and returns a reference. This happens twice and references becomes different (although the values are the same).

    0 讨论(0)
  • 2020-12-06 05:56

    The CIL for your code boxes the two integers and compares the two objects that result from the boxing (==). This comparison is by reference.

      .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
    

    For the .Equals it calls Object.Equals, which calls Int32.Equals (virtual method call on Object):

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

    This casts to int and compares the values as integers, a value type comparison.

    0 讨论(0)
  • 2020-12-06 05:58

    Two objects are equal if they point to the same space in memory.

    val1 == val1; //Equals true
    

    As pointed by tc you can make an operator overload.

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

    This way the behavior of the operator == will be the one defined by this method.

    You should also overload the operator != when you overload ==.

    0 讨论(0)
  • 2020-12-06 05:59

    == checks whether the two objects are identical. They are not. They represent the same number, but are stored at different locations in memory.

    It’s like comparing two apples. Both are apples and look the same, but they are different objects.

    0 讨论(0)
  • 2020-12-06 06:00

    That is because when you cast them to objects they are "converted" to references to int values. And the two references are not equal. But equals compares the referenced values instead of the references.

    0 讨论(0)
  • 2020-12-06 06:07

    If you aren't using object but a custom class, you can override the == and != operators, and should probably implement the IEqualityComparer<T> interface

    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();
    }
    
    0 讨论(0)
提交回复
热议问题