# Operator overloading (C# reference)

A user-defined type can overload a predefined C# operator. That is, a type can provide the custom implementation of an operation when one or both operands are of that type. The Overloadable operators section shows which C# operators can be overloaded.

Use the `operator`

keyword to declare an operator. An operator declaration must satisfy the following rules:

- It includes both a
`public`

and a`static`

modifier. - A unary operator takes one parameter. A binary operator takes two parameters. In each case, at least one parameter must have type
`T`

or`T?`

where`T`

is the type that contains the operator declaration.

The following example defines a simplified structure to represent a rational number. The structure overloads some of the arithmetic operators:

```
using System;
public readonly struct Fraction
{
private readonly int num;
private readonly int den;
public Fraction(int numerator, int denominator)
{
if (denominator == 0)
{
throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
}
num = numerator;
den = denominator;
}
public static Fraction operator +(Fraction a) => a;
public static Fraction operator -(Fraction a) => new Fraction(-a.num, a.den);
public static Fraction operator +(Fraction a, Fraction b)
=> new Fraction(a.num * b.den + b.num * a.den, a.den * b.den);
public static Fraction operator -(Fraction a, Fraction b)
=> a + (-b);
public static Fraction operator *(Fraction a, Fraction b)
=> new Fraction(a.num * b.num, a.den * b.den);
public static Fraction operator /(Fraction a, Fraction b)
{
if (b.num == 0)
{
throw new DivideByZeroException();
}
return new Fraction(a.num * b.den, a.den * b.num);
}
public override string ToString() => $"{num} / {den}";
}
public static class OperatorOverloading
{
public static void Main()
{
var a = new Fraction(5, 4);
var b = new Fraction(1, 2);
Console.WriteLine(-a); // output: -5 / 4
Console.WriteLine(a + b); // output: 14 / 8
Console.WriteLine(a - b); // output: 6 / 8
Console.WriteLine(a * b); // output: 5 / 8
Console.WriteLine(a / b); // output: 10 / 4
}
}
```

You could extend the preceding example by defining an implicit conversion from `int`

to `Fraction`

. Then, overloaded operators would support arguments of those two types. That is, it would become possible to add an integer to a fraction and obtain a fraction as a result.

You also use the `operator`

keyword to define a custom type conversion. For more information, see User-defined conversion operators.

## Overloadable operators

The following table provides information about overloadability of C# operators:

Operators | Overloadability |
---|---|

+x, -x, !x, ~x, ++, --, true, false | These unary operators can be overloaded. |

x + y, x - y, x * y, x / y, x % y, x & y, x | y, x ^ y, x << y, x >> y, x == y, x != y, x < y, x > y, x <= y, x >= y | These binary operators can be overloaded. Certain operators must be overloaded in pairs; for more information, see the note that follows this table. |

x && y, x || y | Conditional logical operators cannot be overloaded. However, if a type with the overloaded `true` and `false` operators also overloads the `&` or `|` operator in a certain way, the `&&` or `||` operator, respectively, can be evaluated for the operands of that type. For more information, see the User-defined conditional logical operators section of the C# language specification. |

a[i] | Element access is not considered an overloadable operator, but you can define an indexer. |

(T)x | The cast operator cannot be overloaded, but you can define new conversion operators. For more information, see User-defined conversion operators. |

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= | Compound assignment operators cannot be explicitly overloaded. However, when you overload a binary operator, the corresponding compound assignment operator, if any, is also implicitly overloaded. For example, `+=` is evaluated using `+` , which can be overloaded. |

x = y, x.y, c ? t : f, x ?? y, x->y, =>, f(x), as, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, typeof | These operators cannot be overloaded. |

Note

The comparison operators must be overloaded in pairs. That is, if either operator of a pair is overloaded, the other operator must be overloaded as well. Such pairs are as follows:

`==`

and`!=`

operators`<`

and`>`

operators`<=`

and`>=`

operators

## C# language specification

For more information, see the following sections of the C# language specification:

## See also

## Feedback

Loading feedback...