对象判等和重载==操作符
一直以来在实现对象判等时,写完Equals方法之后习惯性地重载==和!=操作符,如下,
代码一:
1 /// <summary>
2 /// 重载相等操作符
3 /// </summary>
4 public static bool operator ==(MyObject lhs, MyObject rhs)
5 {
6 return lhs.Equals(rhs);
7 }
8 /// <summary>
9 /// 重载不等操作符
10 /// </summary>
11 public static bool operator !=(MyObject lhs, MyObject rhs)
12 {
13 return !(lhs.Equals(rhs));
14 }
15
2 /// 重载相等操作符
3 /// </summary>
4 public static bool operator ==(MyObject lhs, MyObject rhs)
5 {
6 return lhs.Equals(rhs);
7 }
8 /// <summary>
9 /// 重载不等操作符
10 /// </summary>
11 public static bool operator !=(MyObject lhs, MyObject rhs)
12 {
13 return !(lhs.Equals(rhs));
14 }
15
最近突然发现这种写法有个隐患,在于我们在对对象进行操作之前,会先判断对象是否为null,
代码二:
1 if (myobject == null)
2 {
3 //do something
4 }
5
2 {
3 //do something
4 }
5
这时如果myobject真的为null的话,由于!=操作符最终要调用当前对象的Equals方法,会在代码一的第6行引发经典错误:
“未将对象引用设置到对象的实例。”
查了一下《Programming C#》,发现重载==操作符应该调用Object类的Equals静态方法,相应的!=也是调用==然后取反:
代码四:
1 /// <summary>
2 /// 重载相等操作符
3 /// </summary>
4 public static bool operator ==(MyObject lhs, MyObject rhs)
5 {
6 return Object.Equals(lhs,rhs);//调用Object类的Equals方法
7 }
8 /// <summary>
9 /// 重载不等操作符
10 /// </summary>
11 public static bool operator !=(MyObject lhs, MyObject rhs)
12 {
13 return !(lhs == rhs);//调用==,取反
14 }
2 /// 重载相等操作符
3 /// </summary>
4 public static bool operator ==(MyObject lhs, MyObject rhs)
5 {
6 return Object.Equals(lhs,rhs);//调用Object类的Equals方法
7 }
8 /// <summary>
9 /// 重载不等操作符
10 /// </summary>
11 public static bool operator !=(MyObject lhs, MyObject rhs)
12 {
13 return !(lhs == rhs);//调用==,取反
14 }
Object类的静态 Equals方法如下:
代码五:
1 public static Boolean Equals(Object objA, Object objB)
2 {
3 //如果objA和objB指向的是同一个对象,返回true。包括null == null的情况。
4 if (objA == objB) return true;
5 //如果objA和objB有一个为null,返回false。
6 if ((objA == null) || (objB == null)) return false;
7 //调用Equals方法判等。
8 return objA.Equals(objB);
9 }
2 {
3 //如果objA和objB指向的是同一个对象,返回true。包括null == null的情况。
4 if (objA == objB) return true;
5 //如果objA和objB有一个为null,返回false。
6 if ((objA == null) || (objB == null)) return false;
7 //调用Equals方法判等。
8 return objA.Equals(objB);
9 }
分析其代码可知,该方法可以处理myobject为null的情况。
因此在重载==操作符时,不应调用当前类的Equals()方法,而要调用Object.Equals(object objA,object objB)静态方法。