Answer the question
In order to leave comments, you need to log in
Did a very detailed experiment on Equals, ReferenceEquals and ==. Conducted observations and made some conclusions. Are my conclusions correct?
I decided to study in detail what exactly Equals, ReferenceEquals and == compare when comparing different objects of the same and different types. I climbed here and read the moments that interested me, it seems that I did not miss any loopholes:
https://docs.microsoft.com/ru-ru/dotnet/csharp/lan...
https://docs.microsoft.com/ru -en/dotnet/api/system...
https://docs.microsoft.com/en-us/dotnet/api/system...
https://docs.microsoft.com/en-us/dotnet/api /system...
And here is the experiment itself with the conclusions:
using System;
using System.Collections.Generic;
using System.Text;
using static System.Console;
namespace Workspace
{
class Program
{
static void Main()
{
//Классы:
A a = new A("Den");
A a2 = new A("Den");
WriteLine(a.Equals(a2)); //False
WriteLine(ReferenceEquals(a, a2)); //False
WriteLine(a == a2); //False
WriteLine();
A a3 = new A("Den");
A a4 = new A("Yan");
WriteLine(a3.Equals(a4)); //False
WriteLine(ReferenceEquals(a3, a4)); //False
WriteLine(a3 == a4); //False
WriteLine();
A a5 = new A("Den");
object a6 = new A("Den");
WriteLine(a5.Equals(a6)); //False
WriteLine(ReferenceEquals(a5, a6)); //False
WriteLine(a5 == a6); //False
WriteLine();
A a7 = new A("Den");
object a8 = new A("Yan");
WriteLine(a7.Equals(a8)); //False
WriteLine(ReferenceEquals(a7, a8)); //False
WriteLine(a7 == a8); //False
WriteLine();
////////////////////////////////////////
WriteLine();
WriteLine();
WriteLine();
A b = new B("Den", 19);
A b2 = new B("Den", 19);
WriteLine(b.Equals(b2)); //False
WriteLine(ReferenceEquals(b, b2)); //False
WriteLine(b == b2); //False
WriteLine();
A b3 = new B("Den", 19);
A b4 = new B("Yan", 19);
WriteLine(b3.Equals(b4)); //False
WriteLine(ReferenceEquals(b3, b4)); //False
WriteLine(b3 == b4); //False
WriteLine();
A b5 = new B("Den", 19);
object b6 = new B("Den", 19);
WriteLine(b5.Equals(b6)); //False
WriteLine(ReferenceEquals(b5, b6)); //False
WriteLine(b5 == b6); //False
WriteLine();
A b7 = new B("Den", 19);
object b8 = new B("Yan", 19);
WriteLine(b7.Equals(b8)); //False
WriteLine(ReferenceEquals(b7, b8)); //False
WriteLine(b7 == b8); //False
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
//Структуры:
A2 a222 = new A2(2, 1, 3);
A2 a22 = new A2(2, 1, 3);
WriteLine(a222.Equals(a22)); //True
WriteLine(ReferenceEquals(a222, a22)); //False
//WriteLine(a222 == a22); оператор == невозможно применить к структуре
WriteLine();
A2 a23 = new A2(2, 1, 3);
A2 a24 = new A2(2, 4, 3);
WriteLine(a23.Equals(a24)); //False
WriteLine(ReferenceEquals(a23, a24)); //False
WriteLine();
A2 a25 = new A2(2, 1, 3);
object a26 = new A2(2, 1, 3);
WriteLine(a25.Equals(a26)); //True
WriteLine(ReferenceEquals(a25, a26)); //False
WriteLine();
A2 a27 = new A2(2, 1, 3);
object a28 = new A2(2, 4, 3);
WriteLine(a27.Equals(a28)); //False
WriteLine(ReferenceEquals(a27, a28)); //False
WriteLine();
////////////////////////////////////////
WriteLine();
WriteLine();
WriteLine();
A2 a22222 = new A2(2, 1, 3);
B2 a2222 = new B2(2, 1, 3);
WriteLine(a22222.Equals(a2222)); //False
WriteLine(ReferenceEquals(a22222, a2222)); //False
WriteLine();
A2 a223 = new A2(2, 1, 3);
B2 a224 = new B2(2, 4, 3);
WriteLine(a223.Equals(a224)); //False
WriteLine(ReferenceEquals(a223, a224)); //False
WriteLine();
A2 a225 = new A2(2, 1, 3);
object a226 = new B2(2, 1, 3);
WriteLine(a225.Equals(a226)); //False
WriteLine(ReferenceEquals(a225, a226)); //False
WriteLine();
A2 a227 = new A2(2, 1, 3);
object a228 = new B2(2, 4, 3);
WriteLine(a227.Equals(a228)); //False
WriteLine(ReferenceEquals(a227, a228)); //False
WriteLine();
object a229 = new A2(2, 1, 3);
object a220 = new B2(2, 1, 3);
WriteLine(a229.Equals(a220)); //False
WriteLine(ReferenceEquals(a229, a220)); //False
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
//Массивы:
int[] c = new int[5];
int[] c2 = new int[5];
WriteLine(c.Equals(c2)); //False
WriteLine(ReferenceEquals(c, c2)); //False
WriteLine(c == c2); //False
WriteLine();
long[] c3 = new long[5];
int[] c4 = new int[5];
WriteLine(c3.Equals(c4)); //False
WriteLine(ReferenceEquals(c3, c4)); //False
/*WriteLine(c3 == c4);*/ //Из-за разности типов (long[] и int[]) - невозможно применить
WriteLine();
for (int i = 0; i < c.Length; i++)
{
c[i] = i;
c2[i] = i;
c3[i] = i;
c4[i] = i;
}
WriteLine(c.Equals(c2)); //False
WriteLine(ReferenceEquals(c, c2)); //False
WriteLine(c == c2); //False
WriteLine();
WriteLine(c3.Equals(c4)); //False
WriteLine(ReferenceEquals(c3, c4)); //False
WriteLine();
c2[2] = 45;
c4[2] = 55;
WriteLine(c.Equals(c2)); //False
WriteLine(ReferenceEquals(c, c2)); //False
WriteLine(c == c2); //False
WriteLine();
WriteLine(c3.Equals(c4)); //False
WriteLine(ReferenceEquals(c3, c4)); //False
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
WriteLine();
//String:
string d = "8";
string d2 = "8";
WriteLine(d.Equals(d2)); //True
WriteLine(ReferenceEquals(d, d2)); //True
WriteLine(d == d2); //True
WriteLine();
string d3 = "8";
object d4 = "8";
WriteLine(d3.Equals(d4)); //True
WriteLine(ReferenceEquals(d3, d4)); //True
WriteLine(d3 == d4); //True
WriteLine();
string d5 = new string("8");
string d6 = new string("8");
WriteLine(d5.Equals(d6)); //True
WriteLine(ReferenceEquals(d5, d6)); //False
WriteLine(d5 == d6); //True
WriteLine();
string d7 = new string("8");
object d8 = new string("8");
WriteLine(d7.Equals(d8)); //True
WriteLine(ReferenceEquals(d7, d8)); //False
WriteLine(d7 == d8); //False
WriteLine();
object d9 = new string("8");
object d0 = new string("8");
WriteLine(d9.Equals(d0)); //True
WriteLine(ReferenceEquals(d9, d0)); //False
WriteLine(d9 == d0); //False
WriteLine();
////////////////////////////////////////
WriteLine();
WriteLine();
WriteLine();
string d01 = "8";
string d02 = "9";
WriteLine(d01.Equals(d02)); //False
WriteLine(ReferenceEquals(d01, d02)); //False
WriteLine(d01 == d02); //False
WriteLine();
string d03 = "8";
object d04 = "9";
WriteLine(d03.Equals(d04)); //False
WriteLine(ReferenceEquals(d03, d04)); //False
WriteLine(d03 == d04); //False
WriteLine();
string d05 = new string("8");
string d06 = new string("9");
WriteLine(d05.Equals(d06)); //False
WriteLine(ReferenceEquals(d05, d06)); //False
WriteLine(d05 == d06); //False
WriteLine();
string d07 = new string("8");
object d08 = new string("9");
WriteLine(d07.Equals(d08)); //False
WriteLine(ReferenceEquals(d07, d08)); //False
WriteLine(d07 == d08); //False
WriteLine();
object h = "8";
object hh = "8";
WriteLine(h.Equals(hh)); //True
WriteLine(ReferenceEquals(h, hh)); //True
WriteLine(h == hh); //True
WriteLine();
//Другие примитивные типы:
int g = 5;
int g2 = 5;
WriteLine(g.Equals(g2)); //True
WriteLine(ReferenceEquals(g, g2)); //False
WriteLine(g == g2); //True
WriteLine();
int g3 = 5;
long g4 = 5;
WriteLine(g3.Equals(g4)); //False
WriteLine(ReferenceEquals(g3, g4)); //False
WriteLine(g3 == g4); //True
WriteLine();
int g5 = 5;
object g6 = 5;
WriteLine(g5.Equals(g6)); //True
WriteLine(ReferenceEquals(g5, g6)); //False
//WriteLine(g5 == g6); //Из-за разности типов (int и object) - невозможно применить
WriteLine();
object g7 = 5;
object g8 = 5;
WriteLine(g7.Equals(g8)); //True
WriteLine(ReferenceEquals(g7, g8)); //False
WriteLine(g7 == g8); //False
WriteLine();
//ReferenceEquals --- нельзя переопределить!
//Вывод:
//Если не переопределять:
//Классы:
//Equals: проверяет равенство ссылок
//ReferenceEquals: проверяет равенство ссылок
//==: проверяет равенство ссылок
//Структуры:
//Equals: сравнивает названия(типы) структур и значения соответственных полей\свойств
//ReferenceEquals: проверяет равенство ссылок
//==: не применяется(возможно, можно переопределить, но не проверял это)
//Массивы:
//Equals: проверяет равенство ссылок, несмотря на значения ячеек и возможное равенство соответственных ячеек
//ReferenceEquals: проверяет равенство ссылок
//==: проверяет равенство ссылок, но если разные типы массивов, то применить нельзя
Answer the question
In order to leave comments, you need to log in
It's too early for you to conduct such experiments without knowing the platform and its internals and conclusions.
References are compared stupidly by reference, unless otherwise redefined.
1. I'm wondering, when you compared two ints using ReferenceEquals (and I'll say right away, it will be False), roughly imagined what was happening and why even on one variable it would always be False? And which links are compared? Pointers to a value on the stack? NO!!!!!! Packing occurs and two different objects are compared, even on the same variable.
2. that int and further value types are not inherited from object, but from System.ValueType. ValueType has Equals overridden. So what does it do: it compares types, since we are passing an object (and hello again, native packaging), checks the possibility of bitwise comparison, which applies to primitive types, and if it is not possible, calls Equals for each field (including private ones), and through reflection !!!!!!!!!! And there, if there are significant fields without redefined Equals, hello packaging.
3. Comparing int and long through Equals is still a perversion, but primitive types have overloads of Equals, such as
public bool Equals(int obj)
{
return this == obj;
}
classes are compared by hash.
although you can cheat and redefine the hash
or equal, which is important at some points
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question