Share via


CA1013: オーバーロードする加算および減算で、演算子 equals をオーバーロードします

Item [値]
規則 ID CA1013
カテゴリ Microsoft.Design
互換性に影響する変更点 なし

原因

パブリック型またはプロテクト型で、等値演算子を実装しないまま、加算演算子または減算演算子を実装しています。

規則の説明

加算や減算などの演算を使用して型のインスタンスを組み合わせることができる場合は、ほとんどの場合、同じ構成値を持つ任意の 2 つのインスタンスに対して true を返すように等式を定義する必要があります。

等値演算子のオーバーロードされた実装では、既定の等値演算子を使用できません。 そうすると、スタック オーバーフローが発生します。 等値演算子を実装するには、実装で Object.Equals メソッドを使用します。 次の例を参照してください。

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

違反の修正方法

この規則違反を修正するには、加算演算子および減算演算子と数学的に一致するように等式演算子を実装します。

どのようなときに警告を抑制するか

等式演算子の既定の実装で型に正しい動作が提供されている場合、この規則による警告を抑制しても問題ありません。

例 1

次の例では、この規則に違反する型 (BadAddableType) を定義しています。 この型は、同じフィールド値 true を持つ任意の 2 つのインスタンスが等しいかどうかをテストするために、等価演算子を実装する必要があります。 この型 GoodAddableType は、修正された実装を示します。 この型は非等値演算子も実装し、他の規則を満たすために Equals をオーバーライドすることに注意してください。 完全な実装では、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);
      }
   }
}

例 2

次の例では、このトピックで以前に定義した型のインスタンスを使用して等価性をテストし、等価性演算子の既定の正しい動作を示します。

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

この例を実行すると、次の出力が生成されます。

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

関連項目