Share via


Überschreiben des Gleichheitsoperators beim Überladen von Add und Subtract

Aktualisiert: November 2007

     TypeName

OverloadOperatorEqualsOnOverloadingAddAndSubtract

CheckId

CA1013

Kategorie

Microsoft.Design

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Ein öffentlicher oder geschützter Typ implementiert den Additions- oder Subtraktionsoperator, ohne den Gleichheitsoperator zu implementieren.

Regelbeschreibung

Wenn Instanzen eines Typs mithilfe von Rechenoperationen wie Addition und Subtraktion kombiniert werden können, sollten Sie die Gleichheit fast immer so definieren, dass true zurückgegeben wird, wenn zwei Instanzen die gleichen konstituierenden Werte aufweisen.

Sie können den Standardgleichheitsoperator nicht in einer überladenen Implementierung des Gleichheitsoperators verwenden. Eine solche Vorgehensweise führt zu einem Stapelüberlauf. Verwenden Sie zur Implementierung des Gleichheitsoperators die Object.Equals-Methode. Beispiel:

If (Object.ReferenceEquals(left, Nothing)) Then
    Return Object.ReferenceEquals(right, Nothing)
Else
    Return left.Equals(right)
End If
if (Object.ReferenceEquals(left, null)) 
    return Object.ReferenceEquals(right, null);
return left.Equals(right);

Behandlung von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, implementieren Sie den Gleichheitsoperator so, dass er mathematisch konsistent ist mit dem Additions- und dem Subtraktionsoperator.

Wann sollten Warnungen unterdrückt werden?

Eine Warnung dieser Regel kann gefahrlos unterdrückt werden, wenn die Standardimplementierung des Gleichheitsoperators das richtige Verhalten für den Typ angibt.

Beispiel

Im folgenden Beispiel wird ein Typ (BadAddableType) definiert, der gegen diese Regel verstößt. Dieser Typ sollte den Gleichheitsoperator implementieren, damit zwei Instanzen mit den gleichen Feldwerten bei Gleichheit mit true bewertet werden. Der GoodAddableType-Typ zeigt die korrigierte Implementierung. Sie sehen, dass dieser Typ auch den Ungleichheitsoperator implementiert und Equals überschreibt, damit andere Regeln eingehalten werden. Bei einer vollständigen Implementierung würde auch GetHashCode implementiert werden.

using System;

namespace DesignLibrary
{
   public class BadAddableType
   {
      private int a, b;
      public BadAddableType(int a, int b)
      {
         this.a = a;
         this.b = b;
      }
      // Violates rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
      public static BadAddableType operator +(BadAddableType a, BadAddableType b)
      {
         return new BadAddableType(a.a + b.a, a.b + b.b);
      }
      // Violates rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
      public static BadAddableType operator -(BadAddableType a, BadAddableType b)
      {
         return new BadAddableType(a.a - b.a, a.b - b.b);
      }
      public override string ToString()
      {
         return String.Format("{{{0},{1}}}", a, b);
      }
   }

   public class GoodAddableType
   {
      private int a, b;
      public GoodAddableType(int a, int b)
      {
         this.a = a;
         this.b = b;
      }
      // Satisfies rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
      public static bool operator ==(GoodAddableType a, GoodAddableType b)
      {
         return (a.a == b.a && a.b == b.b);
      }

      // If you implement ==, you must implement !=.
      public static bool operator !=(GoodAddableType a, GoodAddableType b)
      {
         return !(a==b);
      }

      // Equals should be consistent with operator ==.
      public override bool Equals(Object obj)
      {
         GoodAddableType good = obj as GoodAddableType;
         if (obj == null)
            return false;

        return this == good;
      }

      public static GoodAddableType operator +(GoodAddableType a, GoodAddableType b)
      {
         return new GoodAddableType(a.a + b.a, a.b + b.b);
      }

      public static GoodAddableType operator -(GoodAddableType a, GoodAddableType b)
      {
         return new GoodAddableType(a.a - b.a, a.b - b.b);
      }
      public override string ToString()
      {
         return String.Format("{{{0},{1}}}", a, b);
      }
   }
}

Im folgenden Beispiel wird mithilfe der Instanzen der zuvor in diesem Thema definierten Typen ein Test auf Gleichheit durchgeführt, um das Standardverhalten und die richtigen Verhalten des Gleichheitsoperators zu veranschaulichen.

using System;

namespace DesignLibrary
{
    public class TestAddableTypes
    {
       public static void Main()
       {
          BadAddableType a = new BadAddableType(2,2);
          BadAddableType b = new BadAddableType(2,2);
          BadAddableType x = new BadAddableType(9,9);
          GoodAddableType c = new GoodAddableType(3,3);
          GoodAddableType d = new GoodAddableType(3,3);
          GoodAddableType y = new GoodAddableType(9,9);

          Console.WriteLine("Bad type:  {0} {1} are equal? {2}", a,b, a.Equals(b)? "Yes":"No");
          Console.WriteLine("Good type: {0} {1} are equal? {2}", c,d, c.Equals(d)? "Yes":"No");
          Console.WriteLine("Good type: {0} {1} are == ?   {2}", c,d, c==d? "Yes":"No");
          Console.WriteLine("Bad type:  {0} {1} are equal? {2}", a,x, a.Equals(x)? "Yes":"No");
          Console.WriteLine("Good type: {0} {1} are == ?   {2}", c,y, c==y? "Yes":"No");
       }
    }
}

Folgende Ergebnisse werden zurückgegeben:

Bad type:  {2,2} {2,2} are equal? No
Good type: {3,3} {3,3} are equal? Yes
Good type: {3,3} {3,3} are == ?   Yes
Bad type:  {2,2} {9,9} are equal? No
Good type: {3,3} {9,9} are == ?   No

Siehe auch

Referenz

Richtlinien für die Implementierung der Equals-Methode und des Gleichheitsoperators (==)