前几天看了一篇文章,总结下
源代码:
int t1 = 10;
int t2 = 10;
Console.WriteLine(t1 == t2); (对值类型进行比较)
Console.WriteLine(t1.Equals(t2));(值类型中重写了Equal)
object a1 = 15;//a1.GetType = Int32,即父类型a1是object,存储的是子类型Int32
object a2 = 15;
Console.WriteLine(a1 == a2);//false 比较的是object类型,即引用类型,地址不同,所以为false
Console.WriteLine(a1.Equals(a2));//true 虽然调用的是object类中的Equal方法,但最终执行的是值类型Int32中重写的Equal方法,比较的是值
object b1 = new StringBuilder("a1");
object b2 = new StringBuilder("a1");
object b3 = b1;
Console.WriteLine(b1 == b2);//false 比较的是引用类型,所以比较地址
Console.WriteLine(b1.Equals(b2));//false 最终执行的Equal是实际类(StringBuilder)中重写的Equals方式,比较的是引用
Console.WriteLine(b1 == b3);//true
Console.WriteLine(b1.Equals(b3));//true
object c1 = "a1";
object c2 = "a1";
Console.WriteLine(c1 == c2);//true string类特殊,虽然是引用类型,但比较值,而非地址
Console.WriteLine(c1.Equals(c2));//true
Console.Read();
msdn对于 ==和 equals的解释:
== 的解释:
对于预定义的值类型,如果操作数的值相等,则相等运算符 (==) 返回 true,否则返回 false。 对于 string 以外的引用类型,如果两个操作数引用同一个对象,则 == 返回 true。 对于 string 类型,== 比较字符串的值。
equals的解释:
如果当前实例是引用类型,Equals(Object)方法测试引用相等性,并调用Equals(Object)方法等效于调用ReferenceEquals方法。 引用相等性意味着进行比较的对象变量引用同一个对象
如果当前实例是值类型,Equals(Object)方法测试值是否相等
有一个评论说:
== 是静态函数,并不属于某个对象,编译器根据左右参数的类型去执行匹配的重载;
Equals 是虚函数,可以在所有类型里面重写,这样即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals
有一本教材上说:
在比较值类型的相等性时,采用与引用类型相同的规则:ReferenceEquals()用于比较引用,Equals()
用于比较值,比较运算符可以看作一个中间项。但最大的区别是值类型需要装箱,才能把它们转换
为引用,进而才能对它们执行方法。另外, Microsoft 已经在 System.ValueType 类中重载了实例方法
Equals(),以便对值类型进行合适的相等性测试。如果调用 sA.Equals(sB),其中 sA 和 sB 是某个结
构的实例,则根据 sA 和 sB 是否在其所有的字段中包含相同的值,而返回 true 或 false。另一方面,
在默认情况下,不能对自己的结构重载“==”运算符。在表达式中使用(sA==sB)会导致一个编译错
误,除非在有问题的代码中为结构提供了“==”的重载版本。
另外, ReferenceEquals()在应用于值类型时,它总是返回 false,因为为了调用这个方法,值类型
175第Ⅰ部分 C# 语 言
需要装箱到对象中