csharp-sobrecarga-operadores

Operator Overloading in C#

  • 3 min

Operator overloading allows us to redefine the functionality of standard operators (like +, -, *, /, ==, !=…) to work with our own defined types.

This enables us to make objects of these types we define be manipulated in a natural and simple way, similar to primitive types.

To overload an operator in C#, you must define a static method with the operator modifier followed by the operator you want to overload. The method signature must match the operator’s operands.

public static DataType operator Operator(DataType operand1, DataType operand2)
{
    // Implementation of custom behavior
}
Copied!
  • DataType: The data type for which the operator is being overloaded.
  • Operator: The operator you want to overload.
  • operand1, operand2: The operands on which the operator will be applied.

Overloading Arithmetic Operators

It is possible to overload the operators +, -, *, /. Let’s see it with an example 👇.

Suppose we have a Vector2D structure that represents a two-dimensional vector. We want to overload the + operator to add two vectors.

public struct Vector2D
{
    public double X { get; }
    public double Y { get; }

    public Vector2D(double x, double y)
    {
        X = x;
        Y = y;
    }

    public static Vector2D operator +(Vector2D v1, Vector2D v2)
    {
        return new Vector2D(v1.X + v2.X, v1.Y + v2.Y);
    }
}
Copied!

In this example,

  • The static method operator + takes two Vector2D as parameters
  • Returns a new Vector2D which is the sum of the two vectors

Using the Overloaded Operator

Now let’s see how we use our overloaded operator. For this, we instantiate two Vector2D and apply the + operator to them.

Vector2D v1 = new Vector2D(1.0, 2.0);
Vector2D v2 = new Vector2D(3.0, 4.0);
Vector2D result = v1 + v2;

Console.WriteLine($"Result: ({result.X}, {result.Y})");
Copied!

The output of this code will be:

Result: (4.0, 6.0)
Copied!

That is, the overloaded + operator invoked the static method we had defined, to apply the sum to our two vectors. The usage is simple and intuitive.

Overloading Relational Operators

In addition to arithmetic operators, it is also possible to overload relational operators like == and !=. For this, we should also overload the Equals and GetHashCode methods to maintain consistency.

Let’s see it with an example,

public struct Vector2D
{
    public double X { get; }
    public double Y { get; }

    public Vector2D(double x, double y)
    {
        X = x;
        Y = y;
    }

    public static bool operator ==(Vector2D v1, Vector2D v2)
    {
        return v1.X == v2.X && v1.Y == v2.Y;
    }

    public static bool operator !=(Vector2D v1, Vector2D v2)
    {
        return !(v1 == v2);
    }

    public override bool Equals(object obj)
    {
        if (obj is Vector2D)
        {
            Vector2D v = (Vector2D)obj;
            return X == v.X && Y == v.Y;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return X.GetHashCode() ^ Y.GetHashCode();
    }
}
Copied!

Using Overloaded Relational Operators

Once the operators are overloaded, their usage is very simple. Returning to our Vector2D class, it would look like this,

Vector2D v1 = new Vector2D(1.0, 2.0);
Vector2D v2 = new Vector2D(1.0, 2.0);
Vector2D v3 = new Vector2D(3.0, 4.0);

Console.WriteLine(v1 == v2); // True
Console.WriteLine(v1 != v3); // True
Copied!