一直以来在实现对象判等时,写完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)静态方法。