CA1013: El operador de sobrecarga es igual que la suma y resta de sobrecarga

Elemento Valor
RuleId CA1013
Category Microsoft.Design
Cambio importante Poco problemático

Causa

Un tipo público o protegido implementa los operadores de suma o resta sin implementar el operador de igualdad.

Descripción de la regla

Cuando las instancias de un tipo puedan combinarse mediante operaciones como suma y resta, casi siempre deberá definir la igualdad para devolver true para dos instancias cualesquiera que tengan los mismos valores constituyentes.

No se puede usar el operador de igualdad predeterminado en una implementación sobrecargada del operador de igualdad. Si lo hace, se producirá un desbordamiento de pila. Para implementar el operador de igualdad, use el método Object.Equals en su implementación. Consulte el ejemplo siguiente.

if (Object.ReferenceEquals(left, null))
    return Object.ReferenceEquals(right, null);
return left.Equals(right);

Cómo corregir infracciones

Para corregir una infracción de esta regla, implemente el operador de igualdad para que sea matemáticamente coherente con los operadores de suma y resta.

Cuándo suprimir las advertencias

Es seguro suprimir una advertencia de esta regla cuando la implementación predeterminada del operador de igualdad proporciona el comportamiento correcto para el tipo.

Ejemplo 1

En el ejemplo siguiente se define un tipo (BadAddableType) que infringe esta regla. Este tipo debe implementar el operador de igualdad para que dos instancias que tengan los mismos valores de campo den como resultado true para la igualdad. El tipo GoodAddableType muestra la implementación corregida. Tenga en cuenta que este tipo también implementa el operador de desigualdad e invalida Equals para satisfacer otras reglas. Una implementación completa también implementaría 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);
      }
   }
}

Ejemplo 2

En el ejemplo siguiente se comprueba la igualdad mediante el uso de instancias de los tipos que se definieron anteriormente en este tema para ilustrar el comportamiento predeterminado y correcto para el operador de igualdad.

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

Este ejemplo produce el siguiente resultado:

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

Vea también