Equal与==区别(摘录)

==比较的是栈内的内容,就是值类型的比较或者对引用的比较。
值类型用“==”比较,就是比较的值,引用类型比较则是比较这两个引用类型的存在栈内的地址是否相同。
 
Equals()分为虚拟方法和静态方法两种,如果比较的是引用,同ReferenceEquals(),

但是Equals()的虚拟方法常常被override,以比较引用类型实际的值,这是它最重要的用途,比如.Net的string类就重写了Equals()方法,用于比较两个字符串的值是否相等,而不是引用是否相等。如果值类型用Equals()方法比较的话,结果一定返回为false,因为必须先进行装箱操作。

 

MS参考中文版:http://msdn.microsoft.com/zh-cn/library/ms173147.aspx
规范中对ReferenceEquals,Equals和操作符==作了如下描述 (部分摘录)
C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,且两者引用的是同一个对象。(In C#, there are two different kinds of equality: reference equality (also known as identity) and value equality. Value equality is the generally understood meaning of equality: it means that two objects contain the same values. For example, two integers with the value of 2 have value equality. Reference equality means that there are not two objects to compare. Instead, there are two object references and both of them refer to the same object. )

若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,请使用 Equals。(To check for reference equality, use ReferenceEquals. To check for value equality, you should generally use Equals. )
重写 Equals
由于 Equals 是一个虚方法,因此任何类都可以重写其实现。表示某个值(本质上可以是任何值类型)一组值(如复数类)的任何类都应该重写 Equals。(Because Equals is a virtual method, any class can override its implementation. Any class that represents a value, essentially any value type, or a set of values as a group, such as a complex number class, should override Equals. )

重写运算符 ==
默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等。因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变(即实例中包含的数据不可更改)时,通过重载运算符 == 来比较值是否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,只要其值相同,就可以将其视为相同。建议不要在非不可变类型中重写运算符 ==。(By default, the operator == tests for reference equality by determining whether two references indicate the same object. Therefore, reference types do not have to implement operator == in order to gain this functionality. When a type is immutable, that is, the data that is contained in the instance cannot be changed, overloading operator == to compare value equality instead of reference equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value. It is not a good idea to override operator == in non-immutable types.)

System.String 类对象初始化后不能改变,是一个应用==规范的好的例子。但是并非.NET 类库都遵守这个规范。举个例子:在System.Drawing.Point中(类似的还有Point, Rectangle, etc), Point 不是一个不可变类型(Point.Offset会改变已初始化的Point对象的状态), 但该类却重载了==并用于值比较。当然我同意Point的实现者是为了符合之前C++中的编程习惯,但毕竟和规范不符。 


- MS对ReferenceEquals和Equals有明确的规范 (橙色引用文字)。未发现和规范不一致的.net类库。
- 对于操作符==,从规范中看出,态度比较暧昧。一方面MS希望接近于Java的==的规范而倾向于引用相等(见上一段蓝色字段。也许是因为.net语言的主设计师曾经是Java的主设计师,也可能是为了照顾J#用户);另一方面为了兼容C++的==重载习惯,对一些值类型依然希望使用操作符==作为值相等的操作符。(上一段的红色字段)从而导致了大家使用时(包括.net类库实现者)的混淆。

posted @ 2009-11-20 20:58  亦心  阅读(774)  评论(0编辑  收藏  举报