Sobrecarga de operadores (referencia de C#)Operator overloading (C# reference)

Un tipo definido por el usuario puede sobrecargar un operador de C# predefinido.A user-defined type can overload a predefined C# operator. Es decir, un tipo puede proporcionar la implementación personalizada de una operación cuando uno o ambos operados son de ese tipo.That is, a type can provide the custom implementation of an operation when one or both of the operands are of that type. En la sección Operadores sobrecargables se muestra qué operadores de C# pueden sobrecargarse.The Overloadable operators section shows which C# operators can be overloaded.

Use la palabra clave operator para declarar un operador.Use the operator keyword to declare an operator. Una declaración de operador debe cumplir las reglas siguientes:An operator declaration must satisfy the following rules:

  • Incluye los modificadores public y static.It includes both a public and a static modifier.
  • Un operador unario toma un parámetro.A unary operator takes one parameter. Un operador binario toma dos parámetros.A binary operator takes two parameters. En cada caso, al menos un parámetro debe ser de tipo T o T? donde T es el tipo que contiene la declaración del operador.In each case, at least one parameter must have type T or T? where T is the type that contains the operator declaration.

En el ejemplo siguiente se muestra una estructura simplificada para representar un número racional.The following example defines a simplified structure to represent a rational number. La estructura sobrecarga algunos de los operadores aritméticos: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
    }
}

Puede ampliar el ejemplo anterior mediante la definición de una conversión implícita de int a Fraction.You could extend the preceding example by defining an implicit conversion from int to Fraction. A continuación, los operadores sobrecargados admiten argumentos de esos dos tipos.Then, overloaded operators would support arguments of those two types. Es decir, sería posible agregar un valor entero a una fracción y obtener como resultado una fracción.That is, it would become possible to add an integer to a fraction and obtain a fraction as a result.

También usa la palabra clave operator para definir una conversión de tipos personalizada.You also use the operator keyword to define a custom type conversion. Para obtener más información, vea Operadores de conversión definidos por el usuario.For more information, see User-defined conversion operators.

Operadores sobrecargablesOverloadable operators

En la tabla siguiente se proporciona información sobre la posibilidad de sobrecarga de los operadores de C#:The following table provides information about overloadability of C# operators:

OperadoresOperators Posibilidad de sobrecargaOverloadability
+x, -x, !x, ~x, ++, --, true, false+x, -x, !x, ~x, ++, --, true, false Estos operadores unarios se pueden sobrecargar.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 >= yx + 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.These binary operators can be overloaded. Determinados operadores deben sobrecargarse en pares; para obtener más información, vea la nota que está a continuación de esta tabla.Certain operators must be overloaded in pairs; for more information, see the note that follows this table.
x && y, x || yx && y, x || y No se pueden sobrecargar los operadores lógicos condicionales.Conditional logical operators cannot be overloaded. 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.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. 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#.For more information, see the User-defined conditional logical operators section of the C# language specification.
a[i]a[i] El acceso a un elemento no se considera un operador sobrecargable, pero puede definir un indizador.Element access is not considered an overloadable operator, but you can define an indexer.
(T)x(T)x El operador de conversión no se puede sobrecargar, pero es posible definir operadores de conversión nuevos.The cast operator cannot be overloaded, but you can define new conversion operators. Para obtener más información, vea Operadores de conversión definidos por el usuario.For more information, see User-defined conversion operators.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= Los operadores de asignación compuestos no pueden sobrecargarse explícitamente.Compound assignment operators cannot be explicitly overloaded. 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.However, when you overload a binary operator, the corresponding compound assignment operator, if any, is also implicitly overloaded. Por ejemplo, += se evalúa con +, que se pueden sobrecargar.For example, += is evaluated using +, which can be overloaded.
x = y, x.y, c ? t : f, x ?? y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, typeofx = y, x.y, c ? t : f, x ?? y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, typeof Estos operadores no se pueden sobrecargar.These operators cannot be overloaded.

Nota

Los operadores de comparación deben sobrecargarse en pares.The comparison operators must be overloaded in pairs. Es decir, si se sobrecarga un operador de un par, el otro operador debe sobrecargarse también.That is, if either operator of a pair is overloaded, the other operator must be overloaded as well. Se emparejan de la siguiente manera:Such pairs are as follows:

  • Operadores == y !=== and != operators
  • Operadores < y >< and > operators
  • Operadores <= y >=<= and >= operators

Especificación del lenguaje C#C# language specification

Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:For more information, see the following sections of the C# language specification:

Vea tambiénSee also