Я сталкивался с этим вопросом довольно много раз, и хотя ответы на него имеют смысл, я хотел сам проверить его с помощью простого консольного приложения.
class Program
{
static void Main(string[] args)
{
// Case 1 : FOR REFERENCE TYPES where class b is a copy of class a
Class1 a = new Class1("Hello");
Class1 b = a;
Console.WriteLine("case 1");
Console.WriteLine(a.GetHashCode());
Console.WriteLine(b.GetHashCode());
Console.WriteLine(a==b); //true
Console.WriteLine(a.Equals(b)); //true
// Case 2 : FOR REFERENCE TYPES where class b is not a copy of class a, but it assigned the same values
// Though the referenced memory addresses are different, the fields of the class are assigned the same values, but will have different hashcodes and are therfore not equal.
Class1 c = new Class1("Hello");
Console.WriteLine(" ");
Console.WriteLine("case 2");
Console.WriteLine(a.GetHashCode());
Console.WriteLine(c.GetHashCode());
Console.WriteLine(a==c);//false
Console.WriteLine(a.Equals(c));//false
// Case 3 : FOR REFERENCE TYPES where two strings are assigned the same values, an exception to the way value types behave.
// using the '==' operstor with strings compares their values not memory addresses.
string s1 = "hi";
string s2 = "hi";
Console.WriteLine(" ");
Console.WriteLine("case 3");
Console.WriteLine(s1 == s2);//true
Console.WriteLine(s1.Equals(s2));//true
//Case 4 : FOR VALUE TYPES - they are the same when comparing the same type.
int x = 5;
int y = 5;
Console.WriteLine(" ");
Console.WriteLine("case 4");
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(x == y);//true
Console.WriteLine(x.Equals(y));//true
// Case 5 : Another value type scenario for completeness
x = y;
Console.WriteLine(" ");
Console.WriteLine("case 5");
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(x.GetType());
Console.WriteLine(y.GetType());
Console.WriteLine(x == y);//true
Console.WriteLine(x.Equals(y));//true
// Case 6 : Yet Another value type scenario for completeness, with different value types.
float z = 5;
Console.WriteLine(" ");
Console.WriteLine("case 6");
Console.WriteLine(x.GetType());
Console.WriteLine(z.GetType());
Console.WriteLine(x);
Console.WriteLine(z);
Console.WriteLine(x == z);//true
Console.WriteLine(x.Equals(z));//false, as the values being compared are of two different types- int and float. The .Equals method expects them to be the same type.
// Case 7 : For giggles, Yet Another ref type scenario for completeness, with objects.
string s3 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
string s4 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
object obj1 = s3;
object obj2 = s4;
Console.WriteLine(" ");
Console.WriteLine("case 7");
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
Console.WriteLine(obj1.GetHashCode());
Console.WriteLine(obj2.GetHashCode());
Console.WriteLine(obj1 == obj2);//false - as they refer to different addresses.
Console.WriteLine(obj1.Equals(obj2));//true - in this case both objects have the same hashcode.
Console.ReadKey();
}
public class Class1
{
string name;
public Class1(string strName)
{
name = strName;
}
}
}
Предположение 1 : Из общедоступных ответов я понял, что для ссылочных типов a == b сравнивает ссылки, тогда как a.Equals (b) сравнивает действительные значения, на которые ссылаются.Это то, что меня оттолкнуло при просмотре результатов моей программы.
Применительно к моей программе, в случае 2 - Несмотря на то, что ссылочные адреса памяти для a и c разные, их полям присваиваются одинаковые значения.Тем не менее a.Equals (c) возвращает false, поскольку они по-прежнему не равны, поскольку имеют разные хеш-коды.Я предполагал, что они вернут истину первоначально на основе предположения 1, но имеет смысл, что они не равны.Но тогда в чем же разница между == и .Equals?
В случае 3 использование оператора '==' со строками сравнивает их значения, а не адреса памяти.
В случае 6типы значений, сравниваемые методом .Equals, различаются, в то время как метод ожидает, что они будут одного типа.Следовательно, он возвращает false.
Что я до сих пор не понимаю, так это случай 7. Почему в этом случае объекты имеют одинаковый хэш-код?Извините за длинный код и заранее спасибо!