Sobrecarga de operador – operadores predefinidos unários, aritméticos, de igualdade e de comparação
Um tipo definido pelo usuário pode sobrecarregar um operador C# predefinido. Ou seja, um tipo pode fornecer a implementação personalizada de uma operação caso um ou ambos os operandos sejam desse mesmo tipo. A seção Operadores sobrecarregáveis mostra quais operadores do C# podem ser sobrecarregados.
Use a palavra-chave operator
para declarar um operador. Uma declaração de operador deve satisfazer as regras a seguir:
- Ela inclui os modificadores
public
estatic
. - Um operador unário tem um parâmetro de entrada. Um operador binário tem dois parâmetros de entrada. Em cada caso, pelo menos um parâmetro deve ter o tipo
T
ouT?
, em queT
é o tipo que contém a declaração do operador.
O exemplo a seguir define uma estrutura simplificada para representar um número racional. A estrutura sobrecarrega alguns dos operadores aritméticos:
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
}
}
Você pode estender o exemplo anterior definindo uma conversão implícita de int
em Fraction
. Em seguida, os operadores sobrecarregados seriam compatíveis com os argumentos desses dois tipos. Ou seja, tornaria-se possível adicionar um inteiro a uma fração e obter uma fração como um resultado.
Use também a palavra-chave operator
para definir uma conversão de tipo personalizado. Para saber mais, confira Operadores de conversão definidos pelo usuário.
Operadores sobrecarregáveis
A tabela a seguir mostra os operadores que podem ser sobrecarregados:
Operadores | Observações |
---|---|
+x , -x , !x , ~x , ++ , -- , true , false |
Os operadores true e false devem ser sobrecarregados juntos. |
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 |
Deve ser sobrecarregado em pares da seguinte maneira: == e != , < e > , <= e >= . |
Operadores não sobrecarregáveis
A tabela a seguir mostra os operadores que não podem ser sobrecarregados:
Operadores | Alternativas |
---|---|
x && y , x || y |
Sobrecarregue os operadores true e false e os operadores & ou | . Para obter mais informações, consulte Operadores lógicos condicionais definidos pelo usuário. |
a[i] , a?[i] |
Defina um indexador. |
(T)x |
Defina conversões de tipo personalizadas que podem ser executadas por uma expressão de conversão. Para saber mais, confira Operadores de conversão definidos pelo usuário. |
+= , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , >>>= |
Sobrecarregue o operador binário correspondente. Por exemplo, quando você sobrecarrega o operador binário + , += é implicitamente sobrecarregado. |
^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 |
Nenhum. |
Especificação da linguagem C#
Para obter mais informações, confira as seguintes seções da especificação da linguagem C#: