误解三:值类型的默认Equals实现是对两个对象进行逐位比较的。
有些人认为值类型的Equals默认实现就是通过比较两个对象在内存中的位表示,即如果所有的二进制位都相等,则说明这两个对象“等同”。这是不准确的。因为其实值类型的Equals默认实现是对值类型的每个字段都调用该字段类型的Equals方法,如果所有字段的Equals方法都返回true,则他们才可能相等。来看一个例子:
?
- class MyClass {
- public override bool Equals(object obj) {
- Console.WriteLine("MyClass的Equals方法被调用了。"); return true;
- } }
- struct MyStruct {
- public MyClass Filed; }
- class Program {
- static void Main(string[] args) {
- MyStruct a; MyStruct b;
- a.Filed = new MyClass(); b.Filed = new MyClass();
- Console.WriteLine(a.Equals(b)); }
- }
很显然,a和b拥有完全不同的二进制位表示。但是最终打印的结果是:
?
- MyClass的Equals方法被调用了。 True
这说明值类型的默认实现是通过调用字段的Equals方法来确定两个对象是否相等,而不是通过比较他们的二进制位是否一致来确定的。
误解四:Equals是非常基本、非常常用的方法,所以其默认的实现不存在性能问题。
对于引用类型,Equals的默认实现很简单,仅仅需要判断两个引用是不是同一种类型、两个引用指向的是不是同一块内存就可以了。所以其性能也没有问题。但是对于值类型,Equals的任务就没有这么简单了。它需要对两个对象的所有字段都做出比较,即逐字段调用字段类型的Equals。










