MSDN代码示例:为什么在调用静态Object.Equals之前检查null?

时间:2013-07-10 13:11:40

标签: c# equals equality equals-operator

在Microsoft的MSDN Library中有关IEquatable<T>.Equals方法,(http://msdn.microsoft.com/en-us/library/ms131190.aspx)的文章中,提供了一个示例来演示如何重写Equals和Equality运算符。它看起来像这样:

public class Person : IEquatable<Person>
{
   private string uniqueSsn;
   private string lName;

   public bool Equals(Person other) 
   {
      if (other == null) 
         return false;

      if (this.uniqueSsn == other.SSN)
         return true;
      else 
         return false;
   }

   public override bool Equals(Object obj)
   {
      if (obj == null) 
         return false;

      Person personObj = obj as Person;
      if (personObj == null)
         return false;
      else    
         return Equals(personObj);   
   }   

   public static bool operator == (Person person1, Person person2)
   {
      if ((object)person1 == null || ((object)person2) == null) // Here !!!
         return Object.Equals(person1, person2);

      return person1.Equals(person2);
   }
   ...
}

我注意到这一行:if ((object)person1 == null || ((object)person2) == null) return Object.Equals(person1, person2);

根据我的理解,静态Object.Equals会自动检查null的参数。为什么在调用它之前再次检查null呢?这样做是否有指导原则?

我会像这样实现它:

   public static bool operator == (Person person1, Person person2)
   {
         return Object.Equals(person1, person2);
   }

或许这个:

   public static bool operator == (Person person1, Person person2)
   {
      if ((object)person1 == null)
         return ((object)person2 == null)

      return person1.Equals(person2);
   }

根据同一文档中的引用:“如果您覆盖Object.Equals(Object),则在调用类上的static Equals(System.Object, System.Object)方法时也会调用被覆盖的实现”

更新

我在public bool Equals(Person other)中发现了一个可能的错误,它显示为:other == null,其中==超载!虽然结果是正确的,但还有一个额外的间接层。我认为它应该是(object)other == null

1 个答案:

答案 0 :(得分:3)

您的方法最终会调用虚拟 Equals(Object)方法,因为这是Object.Equals的作用。这里给出的方式仅在至少有一个值为null时才使用Object.Equals,以便返回true如果它们都为null,否则为false - 该路径将永远不会回调到您的{ {1}}实施。

如果两个值都为非null,则MSDN方法将非虚拟调用直接调用Equals - 这不仅避免了虚方法间接,还避免了另一种类型检查当我们已经知道如果引用 非空时,它们就是多余的,它们都是bool Equals(Person)引用。

我认为这个例子在使用字段和属性的混合中是不幸的,请注意 - 我肯定会这样写:

Person

只是:

if (this.uniqueSsn == other.SSN)
   return true;
else 
   return false;

或更明显:

return this.uniqueSsn == other.SSN;