2

在微软关于IEquatable<T>.Equals方法的 MSDN 库文章 ( 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);
   }

基于同一文档中的此引用:“如果您这样做 override Object.Equals(Object),则在调用您的类上的方法时也会调用您的重写实现static Equals(System.Object, System.Object)

更新:

我在 中发现了一个可能的错误public bool Equals(Person other),上面写着:other == null哪里==重载了!虽然结果是正确的,但还有一层额外的间接性。我相信它应该是(object)other == null

4

1 回答 1

3

您的方法最终会调用虚拟 Equals(Object)方法,因为它就是这样Object.Equals做的。此处给出的方法仅Object.Equals在至少有一个值为 null 时使用,以便在true它们同时为 null 和 false 时返回 - 该路径永远不会回调到您的Equals实现中。

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

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

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

就像:

return this.uniqueSsn == other.SSN;

或更明显:

return this.uniqueSsn == other.uniqueSsn;
于 2013-07-10T13:16:45.670 回答