Object equality behaves different in .NET

前端 未结 9 1990
旧巷少年郎
旧巷少年郎 2020-12-07 01:58

I have these statements and their\' results are near them.

string a = \"abc\";
string b = \"abc\";

Console.Writeline(a == b); //true

object x = a;
object y         


        
相关标签:
9条回答
  • 2020-12-07 02:50
    string a = "abc"; 
    string b = "abc"; 
    
    Console.Writeline(a == b); //true 
    

    String references are the same for the same string due to String Interning

    object x = a; 
    object y = b; 
    
    Console.Writeline(x == y); // true 
    

    Because the references are the same, two objects created from the same reference are also the same.

    string c = new string(new char[] {'a','b','c'}); 
    string d = new string(new char[] {'a','b','c'}); 
    

    Here you create two NEW arrays of characters, these references are different.

    Console.Writeline(c == d); // true 
    

    Strings have overloaded == to compare by value.

    object k = c; 
    object m = d; 
    

    Since the previous references are different, these objects are different.

    Console.Writeline(k.Equals(m)) //true 
    

    .Equals uses the overloaded String equals method, which again compare by value

    Console.Writeline(k == m); // false 
    

    Here we check to see if the two references are the same... they are not

    The key is figuring out when an equality is comparing references or values.

    Objects, unless otherwise overloaded, compare references.

    Structs, unless otherwise overloaded, compare values.

    0 讨论(0)
  • 2020-12-07 02:57

    The == operator compares references (the memory addresses) while .Equals compares the actual object values. In the case of string, you get lucky and two identical strings can refer to the same address frequently. One of the joys of managed languages.

    0 讨论(0)
  • 2020-12-07 02:59
       string c = new string(new char[] {'a','b','c'});
       string d = new string(new char[] {'a','b','c'});
    
       Console.WriteLine(c == d); // true
    
       object k = c;
       object m = d;
    
       Console.WriteLine(k.Equals(m)); //true
    
       Console.WriteLine(k == m); // false
    

    Generates IL code, like this:

    IL_0001:  ldc.i4.3    
    IL_0002:  newarr      System.Char
    IL_0007:  dup         
    IL_0008:  ldtoken     <PrivateImplementationDetails>{61BB33F4-0CA5-4733-B259-764124AD1A79}.$$method0x6000002-1
    IL_000D:  call        System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray
    IL_0012:  newobj      System.String..ctor
    IL_0017:  stloc.0     
    IL_0018:  ldc.i4.3    
    IL_0019:  newarr      System.Char
    IL_001E:  dup         
    IL_001F:  ldtoken     <PrivateImplementationDetails>{61BB33F4-0CA5-4733-B259-764124AD1A79}.$$method0x6000002-2
    IL_0024:  call        System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray
    IL_0029:  newobj      System.String..ctor
    IL_002E:  stloc.1     
    IL_002F:  ldloc.0     
    IL_0030:  ldloc.1     
    IL_0031:  call        System.String.op_Equality   //STRING EQUALITY 
    IL_0036:  call        System.Console.WriteLine
    IL_003B:  nop         
    IL_003C:  ldloc.0     
    IL_003D:  stloc.2     
    IL_003E:  ldloc.1     
    IL_003F:  stloc.3     
    IL_0040:  ldloc.2     
    IL_0041:  ldloc.3     
    IL_0042:  callvirt    System.Object.Equals
    IL_0047:  call        System.Console.WriteLine
    IL_004C:  nop         
    IL_004D:  ldloc.2     
    IL_004E:  ldloc.3     
    IL_004F:  ceq         //CEQ INSTRUCTION: **VALUES** EQUALITY !
    IL_0051:  call        System.Console.WriteLine
    

    As you can see the last instruction call CEQ instruction that makes comparison of values equality pushed on stack. The values pushed on stack are references of both boxed string, which are not equal.

    0 讨论(0)
提交回复
热议问题