Author :
Complexity : Beginner

### Introduction

Suppose we have one class named Complex Number and we want to implement arithmetic operation on this class. There is two way to do this:

1. By creating Add, Subtract, Multiplication, Division function which will do required operation.

2. By overloading arithmetic operator(+,-,*,/), so that if we write num1 + num2 and it will add two Complex Number just like primitive type. This is done through Operator Overloading.

Operator Overloading provides a way of implementing arithmetic operation on custom type just like primitive type.

Syntax

```access_specifier  return_type  operator Operator_symbol (parameter_list)
{
// Code block
}```

Description​​​

• access_specifier: It can be public, private, protected or internal.
• return_type: Type of the data which will return after performing the operation. It can be any valid C# data type.
• operator: It is a keyword.
• Operator_symbol: The symbol which needs to be overload.
• parameter_list: The list of parameters that are operand for operator symbol.

Example

```// C# program to define overloading of the binary operator
using System;

class TestNumber
{

public int num;

// Constructor
public TestNumber(int n)
{
num = n;
}

public TestNumber()
{
}

public static TestNumber operator +(TestNumber num1, TestNumber num2)
{
TestNumber number = new TestNumber();
number.num = num1.num + num2.num;
return number;
}
}

class OperatorMain
{
public static void Main()
{

TestNumber num1 = new TestNumber(3);
TestNumber num2 = new TestNumber(4);
TestNumber number = num1 + num2;

Console.Write("Result Test Number:\n");
Console.WriteLine("Number = {0}", number.num);
}
}```

Output

```Result Test Number:
Number = 7```

The main advantage of Operator Overloading is that, by using it, the code is easily readable as we write obj1 + obj2 to add two objects.

The below table describes which operator can be overloaded and which can not:

Operators Description
+, -, !, ~, ++, – – Unary operator can be overloaded and they take one operand.
+, -, *, /, % Binary operator can be overloaded and they take two operands.
==, !=, = Comparison operator can be overloaded and they take two operands.
&&, || Conditional logical operators can not be overloaded.
+=, -+, *=, /=, %=, = Assignment operator can not be overloaded.

To overload the unary operator, the operator function takes only one argument and return the object of the containing type. Below code is used to understand the overloading of the unary operator:

```// C# program to define overloading of unary operator
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static ComplexNumber operator ++(ComplexNumber num1)
{
num1 += 1;
return num1;
}

public static ComplexNumber operator +(ComplexNumber num1, int val)
{
ComplexNumber num = new ComplexNumber();
num.real = num1.real + val;
num.img = num1.img + val;
return num;
}

public static ComplexNumber operator +(int val, ComplexNumber num1)
{
return num1 + val;
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber num1 = new ComplexNumber(3, 5);
ComplexNumber result = new ComplexNumber();
//Pre Increment
result = num1++;
Console.Write("Result (Pre Increment) Complex Number:\n");
Console.WriteLine("Real Part = {0}", result.real);
Console.WriteLine("Imaginary Part = {0}", result.img);
Console.WriteLine("Value = {0}\n", result.Value);

//Post Increment
result = ++num1;
Console.Write("Result (Post Increment) Complex Number:\n");
Console.WriteLine("Real Part = {0}", result.real);
Console.WriteLine("Imaginary Part = {0}", result.img);
Console.WriteLine("Value = {0}", result.Value);
}
}```

Output

```Result (Pre Increment) Complex Number:
Real Part =  4
Imaginary Part =  6
Value = 7.21
Result (Post Increment) Complex Number:
Real Part =  4
Imaginary Part =  6
Value = 7.21```

To overload binary operator, operator function takes two arguments and return the object of the containing type. The two arguments maybe both are object type or one is an object type and the other is a number type. Below code is used to understand the overloading binary operator:

Overloading Binary operator with both arguments is of object type (obj1 + obj2)

```// C# program to define overloading of the binary operator
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static ComplexNumber operator +(ComplexNumber num1, ComplexNumber num2)
{
ComplexNumber num = new ComplexNumber();
num.real = num1.real + num2.real;
num.img = num1.img + num2.img;
return num;
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber num1 = new ComplexNumber(3, 5);
ComplexNumber num2 = new ComplexNumber(4, 7);
ComplexNumber num = num1 + num2;

Console.Write("Result Complex Number:\n");
Console.WriteLine("Real Part = {0}", num.real);
Console.WriteLine("Imaginary Part = {0}", num.img);
Console.WriteLine("Value = {0}", num.Value);
}
}
```

Output

```Result Complex Number:
Real Part =  7
Imaginary Part =  12
Value = 13.89```

Overloading Binary operator with the argument is of object type and another argument is of number type (obj1 + 1 or 1 + obj1)

```// C# program to define overloading of the binary operator
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static ComplexNumber operator +(ComplexNumber num1, int val)
{
ComplexNumber num = new ComplexNumber();
num.real = num1.real + val;
num.img = num1.img + val;
return num;
}

public static ComplexNumber operator +(int val, ComplexNumber num1)
{
return num1 + val;
}
}

class OperatorMain
{
public static void Main()
{

ComplexNumber num1 = new ComplexNumber(3, 5);
ComplexNumber numResult1 = num1 + 5;
ComplexNumber numResult2 = 7 + num1;

Console.Write("Result 1 Complex Number:\n");
Console.WriteLine("Real Part = {0}", numResult1.real);
Console.WriteLine("Imaginary Part = {0}", numResult1.img);
Console.WriteLine("Value = {0}\n", numResult1.Value);

Console.Write("Result 2 Complex Number:\n");
Console.WriteLine("Real Part = {0}", numResult2.real);
Console.WriteLine("Imaginary Part = {0}", numResult2.img);
Console.WriteLine("Value = {0}", numResult2.Value);
}
}```

Output

```Result 1 Complex Number:
Real Part =  8
Imaginary Part =  10
Value = 12.81

Result 2 Complex Number:
Real Part =  10
Imaginary Part =  12
Value = 15.62```

To overload relational operator, operator function take two arguments and return a boolean value. The main thing to remember while overloading relational operator is that relational operator needs to overload in pair meaning that if we want to overload '<' then we also overload '>'. Similarly for '==' and '!='. Below code is used to understand overloading relational operator.

```// C# program to define overloading of the relational operator
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static bool operator <(ComplexNumber num1, ComplexNumber num2)
{
return num1.Value < num2.Value;
}

public static bool operator >(ComplexNumber num1, ComplexNumber num2)
{
return num1.Value > num2.Value;
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber num1 = new ComplexNumber(3, 4);
ComplexNumber num2 = new ComplexNumber(3, 5);
bool IsNum1Small = num1 < num2;

if (IsNum1Small)
{
Console.Write("Number 1 is smaller.");
}
else
{
Console.Write("Number2 is smaller.");
}
}
}```

Output

`Number 1 is smaller.`

If we want to overload == operator then we also overload !=. We also need to override Equals() and GetHashCode() functions so that if result is true for == then result also true for Equals() function and return same value from GetHashCode() function.

```// C# program to define overloading of relational operator
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static bool operator ==(ComplexNumber num1, ComplexNumber num2)
{
return num1.Value == num2.Value;
}

public static bool operator !=(ComplexNumber num1, ComplexNumber num2)
{
return num1.Value != num2.Value;
}

public override bool Equals(object obj)
{
ComplexNumber r = obj as ComplexNumber;
if (r != null)
{
return r == this;
}
return false;
}

public override int GetHashCode()
{
return Value.GetHashCode();
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber num1 = new ComplexNumber(3, 4);
ComplexNumber num2 = new ComplexNumber(3, 4);
bool IsNumEqual = num1 == num2;

if (IsNumEqual)
{
Console.Write("Both numbers are equal.");
}
else
{
Console.Write("Both numbers are not equal.");
}
}
}```

Output

`Both numbers are equal.`

We can also implement a conversion operator so that one type can be converted to another type and vice versa. There is two types of conversion as follow:

1. Implicit Conversion
2. Explicit Conversion

### Implicit Conversion

In this case, we will not explicitly typecast source type to target type. Below code is used to understand overloading implicit conversion:

```// C# program to define overloading of implicit conversion
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static implicit operator ComplexNumber(int i)
{
ComplexNumber number = new ComplexNumber(i, 0);
return number;
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber number = 5;

Console.Write("Result Complex Number:\n");
Console.WriteLine("Real Part = {0}", number.real);
Console.WriteLine("Imaginary Part = {0}", number.img);
Console.WriteLine("Value = {0}", number.Value);
}
}```

Output

```Result Complex Number:
Real Part =  5
Imaginary Part =  0
Value = 5```

### Explicit Conversion

In this case, we will explicitly cast source type to target type. Below code is used to understand overloading explicit conversion.

```// C# program to define overloading of explicit conversion
using System;

class ComplexNumber
{
public int real;
public int img;

// Constructor
public ComplexNumber(int r, int i)
{
real = r;
img = i;
}

public ComplexNumber()
{
}

public double Value
{
get
{
return Math.Sqrt(real * real + img * img);
}
}

public static explicit operator double(ComplexNumber number)
{
return Math.Sqrt(number.real * number.real + number.img * number.img);
}
}

class OperatorMain
{
public static void Main()
{
ComplexNumber number = new ComplexNumber(3, 4);
double value = (double)number;

Console.Write("Result Complex Number:\n");
Console.WriteLine("Value = {0}", value);
}
}```

Output

```Result Complex Number:
Value = 5
```