Skip to content

Files

Latest commit

BillWagnerCopilotgewarren
Jun 12, 2025
6c94fe4 · Jun 12, 2025

History

History
100 lines (70 loc) · 9.58 KB
·

operator-overloading.md

File metadata and controls

100 lines (70 loc) · 9.58 KB
·
title description ms.date f1_keywords helpviewer_keywords
Operator overloading - Define unary, arithmetic, equality, and comparison operators.
Learn how to overload a C# operator and which C# operators are overloadable. In general, the unary, arithmetic, equality, and comparison operators are overloadable.
06/11/2025
operator_CSharpKeyword
operator
operator keyword [C#]
operator overloading [C#]

Operator overloading - predefined unary, arithmetic, equality, and comparison operators

A user-defined type can overload a predefined C# operator. That is, a type can provide the custom implementation of an operation in case one or both of the 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 a public modifier.
  • A unary operator has one input parameter. A binary operator has two input parameters. In each case, at least one parameter must have type T or T? where T is the type that contains the operator declaration.
  • It includes the static modifier, except for the compound assignment operators, such as +=.
  • The increment (++) and decrement (--) operators can be implemented as either static or instance methods.

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

:::code language="csharp" source="snippets/shared/OperatorOverloading.cs":::

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 shows the operators that can be overloaded:

Operators Notes
+x, -x, !x, ~x, ++, --, true, false The true and false operators must be overloaded together.
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, x >= y Must be overloaded in pairs as follows: == and !=, < and >, <= and >=.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>= The compound assignment operators can be overloaded in C# 14 and later.

A compound assignment overloaded operator must follow these rules:

  • It must include the public modifier.
  • It can't include the static modifier.
  • The return type must be void.
  • The declaration must include one parameter, which represents the right hand side of the compound assignment.

Beginning with C# 14, the increment (++) and decrement (--) operators can be overloaded as instance members. Instance operators can improve performance by avoiding the creation of a new instance. An instance operator must follow these rules:

  • It must include the public modifier.
  • It can't include the static modifier.
  • The return type must be void.
  • It can't declare any parameters, even if those parameters have a default value.

Non overloadable operators

The following table shows the operators that can't be overloaded:

Operators Alternatives
x && y, x || y Overload both the true and false operators and the & or | operators. For more information, see User-defined conditional logical operators.
a[i], a?[i] Define an indexer.
(T)x Define custom type conversions performed by a cast expression. For more information, see User-defined conversion operators.
^x, x = y, x.y, x?.y, c ? t : f, x ?? y, ??= y,
x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new,
sizeof, stackalloc, switch, typeof, with
None.

Before C# 14, the compound operators can't be overloaded. Overloading the corresponding binary operator implicitly overloads the corresponding compound assignment operator.

Operator overload resolution

Important

This section applies to C# 14 and later. Before C# 14, user-defined compound assignment operators and instance increment and decrement operators aren't allowed.

If x is classified as a variable in a compound assignment expression such as x «op»= y, instance operators are preferred over any static operator for «op». If an overloaded «op»= operator isn't declared for the type of x or x isn't classified as a variable, the static operators are used.

For the postfix operator ++, if x isn't classified as a variable or the expression x++ is used, the instance operator++ is ignored. Otherwise, preference is given to the instance operator ++. For example,

x++; // Instance operator++ preferred.
y = x++; // instance operator++ isn't considered.

The reason for this rule is that y should be assigned to the value of x before it's incremented. The compiler can't determine that for a user-defined implementation in a reference type.

For the prefix operator ++, if x is classified as a variable in ++x, the instance operator is preferred over a static unary operator.

C# language specification

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

See also