Co tak naprawdę dzieje się w takiej sytuacji :
6 przypadków.
using System;
namespace ConsoleApp43
{
class Program
{
static void Main(string[] args)
{
int a = 10, b = 10;
Dog pies1 = new Dog(), pies2 = new Dog();
Console.WriteLine(object.Equals(pies1, pies2));
Console.WriteLine(object.Equals(a, b));
Console.WriteLine(a == b);
Console.WriteLine(int.Equals(a, b));
Console.WriteLine(a.Equals(b));
object c = b;
Console.WriteLine(a.Equals(c));
}
}
class Dog
{
}
}
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 126 (0x7e)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 b,
[2] class ConsoleApp43.Dog pies1,
[3] class ConsoleApp43.Dog pies2,
[4] object c)
IL_0000: nop
// pierwszy przypadek
IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldc.i4.s 10
IL_0006: stloc.1
IL_0007: newobj instance void ConsoleApp43.Dog::.ctor()
IL_000c: stloc.2
IL_000d: newobj instance void ConsoleApp43.Dog::.ctor()
IL_0012: stloc.3
IL_0013: ldloc.2
IL_0014: ldloc.3
IL_0015: call bool [mscorlib]System.Object::Equals(object,
object)
IL_001a: call void [mscorlib]System.Console::WriteLine(bool)
IL_001f: nop
// drugi przypadek
IL_0020: ldloc.0
IL_0021: box [mscorlib]System.Int32
IL_0026: ldloc.1
IL_0027: box [mscorlib]System.Int32
IL_002c: call bool [mscorlib]System.Object::Equals(object,
object)
IL_0031: call void [mscorlib]System.Console::WriteLine(bool)
IL_0036: nop
// trzeci przypadek
IL_0037: ldloc.0
IL_0038: ldloc.1
IL_0039: ceq
IL_003b: call void [mscorlib]System.Console::WriteLine(bool)
IL_0040: nop
// czwarty przypadek
IL_0041: ldloc.0
IL_0042: box [mscorlib]System.Int32
IL_0047: ldloc.1
IL_0048: box [mscorlib]System.Int32
IL_004d: call bool [mscorlib]System.Object::Equals(object,
object)
IL_0052: call void [mscorlib]System.Console::WriteLine(bool)
IL_0057: nop
// piąty przypadek
IL_0058: ldloca.s a
IL_005a: ldloc.1
IL_005b: call instance bool [mscorlib]System.Int32::Equals(int32)
IL_0060: call void [mscorlib]System.Console::WriteLine(bool)
IL_0065: nop
// szósty przypadek
IL_0066: ldloc.1
IL_0067: box [mscorlib]System.Int32
IL_006c: stloc.s c
IL_006e: ldloca.s a
IL_0070: ldloc.s c
IL_0072: call instance bool [mscorlib]System.Int32::Equals(object)
IL_0077: call void [mscorlib]System.Console::WriteLine(bool)
IL_007c: nop
IL_007d: ret
} // end of method Program::Main
Warto omówić przypadek 2.
Widać że w przypadku typu wartościowego następuje opakowanie ,następnie wywoływana jest metoda
Object::Equals(object, object)
.method public hidebysig static bool Equals(object objA,
object objB) cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: bne.un.s IL_0006
IL_0004: ldc.i4.1
IL_0005: ret
IL_0006: ldarg.0
IL_0007: brfalse.s IL_000c
IL_0009: ldarg.1
IL_000a: brtrue.s IL_000e
IL_000c: ldc.i4.0
IL_000d: ret
IL_000e: ldarg.0
IL_000f: ldarg.1
IL_0010: callvirt instance bool System.Object::Equals(object)
IL_0015: ret
} // end of method Object::Equals
Jeśli referencje są równe to zwracana jest wartość true ( tylko w przypadku typów referencyjnych może tak być )
jeśli , któraś z referencji jest null to zwracane jest - false
Jeśli nie zachodzi żaden z tych przypadków tzn. referencje nie są równe i nie są null
wywoływana jest kolejna metoda tym razem instancyjna :
instance bool System.Object::Equals(object)
która wygląda tak:
.method public hidebysig newslot virtual
instance bool Equals(object obj) cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call bool System.Runtime.CompilerServices.RuntimeHelpers::Equals(object,
object)
IL_0007: ret
} // end of method Object::Equals
ta metoda z kolei wywołuje następną metodę, która wygląda tak:
.method public hidebysig static bool Equals(object o1,
object o2) cil managed internalcall
{
.custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 )
} // end of method RuntimeHelpers::Equals
// Denotes the method body is provided bythe CLI itself
Z tego kodu wynika, że metoda System.Object::Equals(object, object) nie jest wirtualna i nie może być nadpisana w strukturze Int32
, natomiast metoda bool Equals(object obj) jest nadpisana i wygląda tak:
.method public hidebysig newslot virtual final
instance bool Equals(int32 obj) cil managed
{
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldind.i4
IL_0002: ldarg.1
IL_0003: ceq
IL_0005: ret
} // end of method Int32::Equals
Metoda ta ma modyfikator : override sealed