MSDN参考地址:
https://docs.microsoft.com/zh-cn/dotnet/api/system.object.equals
private void Test() { int i = 10; int j = 100; Equal(i,j); i = 100; Equal(i, j); i = j; Equal(i, j); System.Diagnostics.Debug.Print($"=============================="); StringBuilder c = new StringBuilder("AAA"); StringBuilder d = new StringBuilder("BBB"); Equal(c, d); d = new StringBuilder("AAA"); Equal(c, d); c = d; d.Append("CCC"); Equal(c, d); } private void Equal(dynamic a, dynamic b) { System.Diagnostics.Debug.Print($"{nameof(a)}={a};{nameof(b)}={b};==:{a==b}"); System.Diagnostics.Debug.Print($"{nameof(a)}={a};{nameof(b)}={b};Equals:{a.Equals(b)}"); }
a=10;b=100;==:False a=10;b=100;Equals:False
a=100;b=100;==:True a=100;b=100;Equals:True
a=100;b=100;==:True a=100;b=100;Equals:True ============================== a=AAA;b=BBB;==:False a=AAA;b=BBB;Equals:False
a=AAA;b=AAA;==:False a=AAA;b=AAA;Equals:True
a=AAACCC;b=AAACCC;==:True a=AAACCC;b=AAACCC;Equals:True
结论:
==
值类型和string类型比较的是对象的值是否相等。
除string类型以外的引用类型比较的是在栈中存储的地址是否相等。
操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
Equals
值类型和string类型比较的是对象的值是否相等。
除string类型以外的引用类型比较的为是否同一引用对象。
操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。
每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。
每次实现 IComparable 时都要重写 Equals 方法。
实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。
不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。
有关 Equals 方法的相关信息,请参见实现 Equals 方法。
在值类型中实现相等运算符 (==)
大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。