Albahari在书中已经说的非常好了,现在摘录如下:
== and !=
The subtleties with == and != arise because they are operators, and so are statically resolved (in fact, they are implemented as static functions). So, when you use == or !=, C# makes a compile-time decision as to which type will perform the comparison, and no virtual behavior comes into play.
仔细体会下列代码:
class Foo{}
void Main()
{
//the compiler hard-wires == to the int type
int x = 5;
int y = 5;
Console.WriteLine (x == y);
//the compiler wires the == operator to the object type
//object’s == operator uses referential equality to compare x and y
object xt = 5;
object yt = 5;
Console.WriteLine (xt == yt);
//Equals is resolved at runtime—according to the object’s actual type
object xo = 5;
object yo = 5;
Console.WriteLine (xo.Equals (yo));
//With reference types, Equals performs referential equality comparison by default;
object o1 = new Foo();
object o2 = new Foo();
Console.WriteLine (o1.Equals(o2));
}
最佳实践:
1)==与Equals的区别:==是按照编译时类型判定,而Equals是按照运行时类型判定。
2)重写引用类型的Equals方法以便实现自定义的判等。
3)保留==以便执行引用判等。
Overloading == and !=
In addition to overriding Equals, you can optionally overload the equality and inequality operators. This is nearly always done with structs, because the consequence of not doing so is that the == and != operators will simply not work on your type.
With classes, there are two ways to proceed:
- Leave == and != alone—so that they apply referential equality.
- Overload == and != in line with Equals.
The first approach is most common with custom types—especially mutable types. It ensures that your type follows the expectation that == and != should exhibit referential equality with reference types and this avoids confusing consumers. We saw an example earlier:
var sb1 = new StringBuilder ("foo");
var sb2 = new StringBuilder ("foo");
Console.WriteLine (sb1 == sb2); // False (referential equality)
Console.WriteLine (sb1.Equals (sb2)); // True (value equality)
The second approach makes sense with types for which a consumer would never want referential equality. These are typically immutable—such as the string and System.Uri classes—and are sometimes good candidates for structs.
总结如下:
1)如果想保留引用相等的比较则不用处理;
2)如果从来不需要进行引用相等的比较,则可以重载此操作符以简化判等操作。