2

メソッドに関する Microsoft の MSDN ライブラリの記事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

4

1 に答える 1

3

あなたのアプローチは、仮想 Equals(Object)メソッドを呼び出すことになりObject.Equalsます。ここで指定されている方法Object.Equalsは、値の少なくとも 1 つが null の場合にのみ使用され、trueそれ以外の場合は null と false の両方である場合に返されます。そのパスはEquals実装にコールバックすることはありません。

両方の値が非 null の場合、MSDN アプローチは非仮想呼び出しを直接行います。これにより、仮想メソッドの間接化だけでなく、参照非 nullbool 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 に答える