Operator overloading allows you to customize the behaviors of C# operators depending on the type of its operands. Operator overloading allows a C# operator to interpret objects in a different way. Consider the example below.

Example 1 – Not Taking Advantage of Operator Overloading

The highlighted code is not acceptable because the compiler doesn’t

namespace OperatorOverloadingDemo
{
    class MyNumber
    {
        public int Number { get; set; }
    }
 
    class Program
    {
        public static void Main()
        {
            MyNumber firstNumber = new MyNumber();
            MyNumber secondNumber = new MyNumber();
 
            firstNumber.Number = 10;
            secondNumber.Number = 5;
 
            MyNumber sum = firstNumber + secondNumber; 
        }
    }
}

know what to add for those two objects. The behavior we want is to add the values of each of the Number property of the two operands and then create a new object containing the sum. This new object is then assigned to the sum variable.

Overloading Binary Operators

The program was modified to add operator overloading to a binary operator (+) which accepts two operands.

using System;
 
namespace OperatorOverloadingDemo2
{
    class MyNumber
    {
        public int Number { get; set; }
 
        public static MyNumber operator +(MyNumber n1, MyNumber n2)
        {
            MyNumber result = new MyNumber();
            result.Number = n1.Number + n2.Number;
            return result;
        }
    }
 
    class Program
    {
        public static void Main()
        {
            MyNumber firstNumber = new MyNumber();
            MyNumber secondNumber = new MyNumber();
 
            firstNumber.Number = 10;
            secondNumber.Number = 5;
 
            MyNumber sum = firstNumber + secondNumber;
 
            Console.WriteLine("Sum = {0}", sum.Number);
        }
    }
}

Example 2 – Using Operator Overloading

Sum = 15

We add the code for operator overloading inside the class that will use it. The syntax for operator overloading is as follows:

public static returnType operator operatorSymbol(type operand1, type operand2)
{
   //Codes here
   return result;
}

As you can see, operator overloading uses a public static method. It must be static because all the class instance will use this method. It must be public so it can be used outside of the class. We then use the operator keyword followed by the symbol of that operator such as + or . Overloading a binary operator requires two operands so the method has two parameters that will accept these operands. Inside the code, another object is declared which will hold the result variable. We add the Number properties of the two parameters and then store the result to the Number property of the result object. Finally, we returned the result object back to the caller. That result object is then assigned to the sum variable. The code below is possible to have the same effect.

MyNumber sum = new MyNumber();
sum.Number = firstNumber.Number + secondNumber.Number;

But using operator overloading, we reduced to just this:

MyNumber sum = firstNumber + secondNumber;

Not all operators can be overloaded. You cannot overload, for example, the += operator. As an alternative, you can overload the +operator and that will automatically apply when you use the += operator. Another thing is > or < must be overloaded in pairs. For example, you cannot just overload the <.

public static bool operator >(MyNumber n1, MyNumber n2)
{
    return (n1.Number > n2.Number);
}

public static bool operator <(MyNumber n1, MyNumber n2)
{
    return (n1.Number < n2.Number);
}

Overloading Unary Operators

Overloading a unary operator is just as easy. All you have to do is provide one parameter because unary operators accept 1 operand. For example, let’s take a look at how we can overload the ++ unary operator.

public static MyNumber operator ++(MyNumber n1)
{
    MyNumber result = new MyNumber();
    result.Number = n1.Number + 1;
    return result;
}

We can see that the code is similar to overloading a binary operator. We created a result object and assigned the new value of Numberinto it. We returned that result to the caller.