Sobrecarga de operadores (referencia de C#)
Un tipo definido por el usuario puede sobrecargar un operador de C# predefinido. Es decir, un tipo puede proporcionar la implementación personalizada de una operación cuando uno o los dos operandos son de ese tipo. En la sección Operadores sobrecargables se muestra qué operadores de C# pueden sobrecargarse.
Use la palabra clave operator para declarar un operador. Una declaración de operador debe cumplir las reglas siguientes:
- Incluye los modificadores
publicystatic. - Un operador unario tiene un parámetro de entrada. Un operador binario tiene dos parámetros de entrada. En cada caso, al menos un parámetro debe ser de tipo
ToT?dondeTes el tipo que contiene la declaración del operador.
En el ejemplo siguiente se muestra una estructura simplificada para representar un número racional. La estructura sobrecarga algunos de los operadores aritméticos:
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
}
}
Puede ampliar el ejemplo anterior mediante la definición de una conversión implícita de int a Fraction. A continuación, los operadores sobrecargados admiten argumentos de esos dos tipos. Es decir, sería posible agregar un valor entero a una fracción y obtener como resultado una fracción.
También usa la palabra clave operator para definir una conversión de tipos personalizada. Para obtener más información, vea Operadores de conversión definidos por el usuario.
Operadores sobrecargables
En la tabla siguiente se proporciona información sobre la posibilidad de sobrecarga de los operadores de C#:
| Operadores | Posibilidad de sobrecarga |
|---|---|
| +x, -x, !x, ~x, ++, --, true, false | Estos operadores unarios se pueden sobrecargar. |
| 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 | Estos operadores binarios se pueden sobrecargar. Determinados operadores deben sobrecargarse en pares; para obtener más información, vea la nota que está a continuación de esta tabla. |
| x && y, x || y | No se pueden sobrecargar los operadores lógicos condicionales. Sin embargo, si un tipo con los operadores true y false sobrecargados, también sobrecarga el operador & o | de determinada manera, el operador && o ||, respectivamente, se puede evaluar para los operandos de ese tipo. Para obtener más información, vea la sección Operadores lógicos condicionales definidos por el usuario de la Especificación del lenguaje C#. |
a[i], a?[i] |
El acceso a un elemento no se considera un operador sobrecargable, pero puede definir un indizador. |
| (T)x | No se puede sobrecargar el operador de conversión, pero pueden definirse conversiones de tipos personalizadas que pueden realizarse mediante una expresión de conversión. Para obtener más información, vea Operadores de conversión definidos por el usuario. |
| +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= | Los operadores de asignación compuestos no pueden sobrecargarse explícitamente. Pero cuando se sobrecarga un operador binario, el operador de asignación compuesto correspondiente, si lo hay, también se sobrecarga de modo implícito. Por ejemplo, += se evalúa con +, que se pueden sobrecargar. |
^x, x = y, x.y, x?.y, c ? t : f, x ?? y, x ??= y, x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, switch, typeof, with |
Estos operadores no se pueden sobrecargar. |
Nota
Los operadores de comparación deben sobrecargarse en pares. Es decir, si se sobrecarga un operador de un par, el otro operador debe sobrecargarse también. Se emparejan de la siguiente manera:
- Operadores
==y!= - Operadores
<y> - Operadores
<=y>=
Especificación del lenguaje C#
Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:
Vea también
- Referencia de C#
- Operadores y expresiones de C#
- Operadores de conversión definidos por el usuario
- Directrices de diseño: sobrecargas de operador
- Directrices de diseño: operadores de igualdad
- Why are overloaded operators always static in C#? (¿Por qué los operadores sobrecargados son siempre estáticos en C#?)