-1

Unable To Overload != , Error 3 The operator 'ConsoleApplication13.pl.operator !=(ConsoleApplication13.pl, ConsoleApplication13.pl)' requires a matching operator '==' to also be defined C:\Users\htg\documents\visual studio 2013\Projects\ConsoleApplication13\ConsoleApplication13\Program.cs 37 28 ConsoleApplication13 .

class Program
{
    static void Main(string[] args)
    {
        pl a ,b,c;
       a= new pl();
        b=new pl();
        a.mark=99;
        b.mark=10;
        c = a+b;
        if (c != b)
            Console.WriteLine("is not equal");
        else
            Console.WriteLine("both are equal");
        Console.WriteLine(c.mark);
       Console.ReadLine();
    }
}
class pl
{
    public int mark;
    public static pl operator+ ( pl a , pl b) // 1. here It Work's Perfectly At + overloading
    {
        pl mm = new pl();
        mm.mark = a.mark + b.mark;
        return mm;

    }
    public static bool operator!= (pl m , pl n) // 2. unable to overload
    {
        if (m.mark != n.mark)
            return true;
        else
            return false;
    }       
}
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • When overloading `!=` you *have to overload* `==` as well; it's highly recommended to overload `Equals()` and `GetHashcode()` in addition – Dmitry Bychenko Dec 04 '15 at 07:12
  • As an aside, I'd *strongly* urge you to avoid public fields, and to put more effort into using meaningful and conventional names. – Jon Skeet Dec 04 '15 at 07:14
  • Read the error message, please. It _very clearly_ states that operator!= "requires a matching operator '==' to also be defined". – jv110 Aug 19 '17 at 20:57

2 Answers2

1

Yes - C# requires that if you overload the != operator, you also overload the == operator. From the C# 5 specification, section 10.10.2:

Certain binary operators require pair-wise declaration. For every declaration of either operator of a pair, there must be a matching declaration of the other operator of the pair. Two operator declarations match when they have the same return type and the same type for each parameter. The following operators require pair-wise declaration:

  • operator == and operator !=
  • operator > and operator <
  • operator >= and operator <=

In this case, it looks like you want:

public static bool operator ==(pl m, pl n)
{
    if (ReferenceEquals(m, n))
    {
        return true;
    }
    if (ReferenceEquals(m, null) || ReferenceEquals(n, null))
    {
        return false;
    }
    return m.mark == n.mark;
}    

public static bool operator !=(pl m, pl n)
{
     return !(m == n);
}

Note how != is implemented in terms of == - this is almost always the simplest approach to implementing these operators. Implement == fully as it's easier to think in terms of positives, and then implement != as the inverse. The ReferenceEquals checks are performed to mean that null == null is true, but anything non-null is not equal to null. (This is also a common optimization to ensure that x == x is true without performing any further tests.)

As noted in comments, it's also very unusual to overload == and != without also overriding GetHashCode and Equals(object); I'd also recommend implementing IEquatable<T>. You should implement those to be compatible with your == operator - the GetHashCode method would probably be best just returning mark.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • `return m.mark == n.mark;` in the `==` operator is not enough, what if `n` or `m` or both are `null`? – Dmitry Bychenko Dec 04 '15 at 07:20
  • @DmitryBychenko: True, was only going by the original implementation. Will fix. – Jon Skeet Dec 04 '15 at 07:21
  • yes but why we need to overload both != As well as == or vice versa , see when you are overloading (a!=b) , it will give you result that's it than again why we need to check for(a==b) And It Does Not Make Any Sense – HitesH JaiN Dec 04 '15 at 07:52
  • @vivek: You need to overload them both because it would be *really* confusing to only overload one. I'm afraid I couldn't understand your comment of "see when you are overloading (a!=b) , it will give you result that's it than again why we need to check for(a==b)". If you're asking why the compiler doesn't automatically provide the other overload - that would be possible in some cases, but not in others. (It's possible to overload those operators not to return `bool`, for example.) – Jon Skeet Dec 04 '15 at 08:20
1

When implementing != you have to implement == as well; it's highly recommended to override both Equals and GetHashCode:

  class pl {
    public int mark;

    ...

    public override bool Equals(object obj) {
      pl other = obj as pl;

      return Object.ReferenceEquals(null, other) ? false : mark == other.mark;
    }

    public override int GetHashCode() {
      return mark;
    }

    public static Boolean operator ==(pl left, pl right) {
      // what if left or right or both are null?
      if (Object.ReferenceEquals(left, right))
        return true;
      else if (Object.ReferenceEquals(left, null))
        return false;
      else if (Object.ReferenceEquals(null, right))
        return false;

      return left.mark == right.mark;
    }

    public static Boolean operator !=(pl left, pl right) {
      return ! (left == right);
    }
  }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • yes but why we need to overload both != As well as == or vice versa , see when you are overloading (a!=b) , it will give you result that's it than again why we need to check for(a==b) And It Does Not Make Any Sense – HitesH JaiN Dec 04 '15 at 07:52