Udostępnij za pośrednictwem


CA1013: Przeciąż operator equals przeciążając operatory add i subtract

TypeName

OverloadOperatorEqualsOnOverloadingAddAndSubtract

CheckId

CA1013

Kategoria

Microsoft.Design

Zmiana kluczowa

Niekluczowa

Przyczyna

Typ publiczny lub chroniony implementuje operator dodawanie lub odejmowanie bez stosowania implementacji operatora równości.

Opis reguły

Podczas gdy wystąpienia typu można łączyć za pomocą operacji takich jak dodawanie i odejmowanie, prawie zawsze należy zdefiniować równość, aby zwracała true dla dwóch wystąpień, które mają te same wartości składowe.

Nie można używać domyślnego operatora równości w przeciążonej implementacji operatora równości.Spowoduje to przepełnienie stosu.Aby zaimplementować operator równości, należy użyć metody Object.Equals w implementacji.Zobacz przykład poniżej.

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);

Jak naprawić naruszenia

Aby naprawić naruszenie tej zasady, należy zaimplementować operator równości tak, aby był matematycznie zgodny z operatorem dodawania i odejmowania.

Kiedy pominąć ostrzeżenia

Można bezpiecznie pominąć ostrzeżenie od tej reguły, podczas gdy domyślna implementacja operatora równości zapewnia poprawne zachowanie dla typu.

Przykład

W poniższym przykładzie zdefiniowano typ (BadAddableType), który narusza tą regułę.Typ ten powinien implementować operator równości, aby dwa wystąpienia, które mają te same wartości pola dawały wynik true dla równości.Typ GoodAddableType przedstawia prawidłową implementację.Należy zwrócić uwagę na to, że ten typ również implementuje operator nierówności i zastępuje Equals do spełnienia innych reguł.Pełna implementacja implementowałaby także GetHashCode.

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);
      }
   }
}

Poniższy przykład sprawdza równości przy użyciu wystąpienia typów, które zostały zdefiniowane wcześniej w tym temacie, aby zilustrować domyślne i poprawne zachowanie operatora równości.

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");
       }
    }
}

Ten przykład generuje następujące wyniki.

           

Zobacz też

Inne zasoby

Guidelines for Implementing Equals and the Equality Operator (==)