When implementing operator overloads, it is very important to make sure that all related operators and methods are consistent in their implementation.

The following guidelines should be followed:

* When providing ``++operator ==++`` you should also provide ``++operator !=++`` and vice-versa.
* When providing ``++operator ==++`` you should also provide ``++Equals(Object)++`` and ``++GetHashCode()++``.
* When providing ``++operator +++`` or ``++operator -++`` you should also provide ``++operator ==++``, respecting previous guidelines.

This rule raises an issue when any of these guidelines are not followed on publicly-visible type (public, protected or protected internal).

== Noncompliant Code Example

----
using System;

namespace MyLibrary
{
  public class Foo // Noncompliant
  {
    private int left;
    private int right;

    public Foo(int l, int r)
    {
      this.left = l;
      this.right = r;
    }

    public static Foo operator +(Foo a, Foo b)
    {
      return new Foo(a.left + b.left, a.right + b.right);
    }

    public static Foo operator -(Foo a, Foo b)
    {
      return new Foo(a.left - b.left, a.right - b.right);
    }
  }
}
----

== Compliant Solution

----
using System;

namespace MyLibrary
{
  public class Foo
  {
    private int left;
    private int right;

    public Foo(int l, int r)
    {
      this.left = l;
      this.right = r;
    }

    public static Foo operator +(Foo a, Foo b)
    {
      return new Foo(a.left + b.left, a.right + b.right);
    }

    public static Foo operator -(Foo a, Foo b)
    {
      return new Foo(a.left - b.left, a.right - b.right);
    }

    public static bool operator ==(Foo a, Foo b)
    {
      return (a.left == b.left && a.right == b.right);
    }

    public static bool operator !=(Foo a, Foo b)
    {
      return !(a == b);
    }

    public override bool Equals(Object obj)
    {
      Foo a = obj as Foo;
      if (a == null)
        return false;
      return this == a;
    }

    public override int GetHashCode()
    {
       return (this.left * 10) + this.right;
    }
  }
}
----
