标签:
1. public static bool ReferenceEquals(object left, object right)
Object.ReferenceEquals()在两个变量引用到同一个对象时返回true,也就是两个变量具有相同的对象ID。不管比较的类型是引用类型还是值类型的,这个方法总是检测对象ID,而不是对象内容。
string a = "test"; string b = "test"; if (Object.ReferenceEquals(a, b)) { Console.WriteLine("equal"); } else { Console.WriteLine("not equal"); } //equal
当比对两个值类型的时候,Object.ReferenceEquals返回false,即使比较的是同一个值类型对象,也会返回false,因为Object.ReferenceEquals输入的两个参数是object类型,所以需要对两个值类型的参数进行装箱操作,导致两个对象的ID不同。
int i = 5; int j = 5; if (Object.ReferenceEquals(i, j)) { Console.WriteLine("equal"); } else { Console.WriteLine("not equal"); } //not equal if (Object.ReferenceEquals(i, i)) { Console.WriteLine("ReferenceEquals : equal"); } else { Console.WriteLine("ReferenceEquals : not equal"); } //not equal
2.public virtual bool Equals(object right)
Object.Equals()方法使用对象的ID来断定两个变量是否相等。这个默认的Object.Equals()函数的行为与Object.ReferenceEquals()是一样的。但是请注意,值类型是不一样的。System.ValueType并没有重载Object.Equals(),记住,System.ValueType是所有你所创建的值类型(使用关键字struct创建)的基类。两个值类型的变量相等的前提条件是它们的类型和内容都是一样的。ValueType.Equals()实现了这一行为。不幸的是,ValueType.Equals()并不是一个高效的实现。ValueType.Equals()是所有值类型的基类(译注:这里是说这个方法在基类上进行比较)。为了提供正确的行为,它必须比较派生类的所有成员变量,而且是在不知道派生类的类型的情况下。在C#里,这就意味着要使用反射。对反射而言它们有太多的不利之处,特别是在以性能为目标的时候。
当你想改变引用类型默认的Equals()语义试,建议重载Equ()方法。
你必须确保你重新定义的方法能满足数学相等性质:相等的自反性,对称性和传递性。自反性就是说一个对象是等于它自己的,不管对于什么类型,a==a总应该返回true;对称就是说,如果有a==b为真,那么b==a也必须为真;传递性就是说,如果a==b为真,且b==c也为真,那么a==c也必须为真,这就是传递性。
标准模式:
public class Foo { public override bool Equals(object right) { // check null: // the this pointer is never null in C# methods. if (right == null) return false; if (object.ReferenceEquals(this, right)) return true; // Discussed below. if (this.GetType() != right.GetType()) return false; // Compare this type‘s contents here: return CompareFooMembers( this, right as Foo); } private static bool CompareFooMembers(Foo f, Foo b) { //do } }
3.== 操作符
任何时候你创建一个值类型,重新定义操作符==()。原因和实例的Equals()是完全一样的。默认的版本使用的是引用的比较来比较两个值类型。
4.public static bool Equals(object left, object right);
静态的Object.Equals()方法是像下面这样实现的:
public static bool Equals(object left, object right) { // Check object identity if (left == right) return true; // both null references handled above if ((left == null) || (right == null)) return false; return left.Equals (right); }
静态的Equals()是使用左边参数实例的Equals()方法来断定两个对象是否相等。
总结
你应该为了更好的性能而总是为值类型实例提供重载的Equals()方法和操作符==()。当你希望引用类型的相等与对象ID的相等不同时,你应该重载引用类型实例的Equals()。
标签:
原文地址:http://www.cnblogs.com/xanadu123/p/5034405.html