我已经多次遇到过这个问题了,虽然答案很有意义,但我想通过一个简单的控制台应用程序来检查它。
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.为什么对象在这种情况下具有相同的哈希码?对于漫长的代码感到抱歉,并提前致谢!
答案 0 :(得分:3)
我认为要记住的一件事是,使用a == b
,编译器通过查看a
和b
的类型来确定在编译时调用哪个函数。如果a
和b
都是object
类型,编译器将生成对ReferenceEquals
的调用,而如果它们都是类型string
,编译器将生成对string.Equals
的调用。
但是,当编译器看到a.Equals(b)
时,它会生成对a
的{{1}}方法的调用,该方法在运行时确定,因为它是一个虚方法。如果Equals
是一个字符串,那么它将调用执行字符串比较的重载(如您所期望的那样)。如果a
是其他对象,那么它将调用该对象上的重载a
方法(如果它有一个)或Equals
(进行object.Equals
比较)如果它没有“T
答案 1 :(得分:0)
a.Equals(b)
只会执行您编写的代码。这只是一个虚拟方法调用。
默认行为(对于引用类型)只是比较引用。
答案 2 :(得分:0)
如何在Class1中实现Equals()?如果你没有提供一个覆盖Equals的方法,它将使用默认的Equals方法,它只是比较参考值。
答案 3 :(得分:0)
a.equals是java.lang.Object类中的方法,它将传递给它的对象的引用与调用它的对象进行比较。
==是再次检查参考文献的操作员。
湾由于equals是Object类中的方法,因此可以覆盖它并可用于执行任何操作,以比较对象内部的值,比较引用或计算哈希代码并进行比较。 因此,对于String类,equals方法已被覆盖,以比较传递给它的对象的值。