Percursos
/
C#
C#
/
Programa
/
Sobrecarga de operadores
So

Sobrecarga de operadores em C#

2 exercícios

Sobre Sobrecarga de operadores

Os principais operadores aritméticos e de comparação podem ser adaptados para serem usados pelas tuas próprias classes e estruturas. Isto é conhecido como sobrecarga de operadores.

Este artigo é uma discussão aprofundada da sintaxe, bem como de quais os operadores que podem ser sobrecarregados e quais não podem.

A maioria dos operadores tem a forma:

static <return type> operaator <operator symbols>(<parameters>);

Os operadores de conversão de tipo têm a forma:

static (explicit|implicit) operator <cast-to-type>(<cast-from-type> <parameter name>);

Os operadores comportam-se da mesma forma que os métodos estáticos.

  • Um símbolo de operador ocupa o lugar do identificador de um método e tem parâmetros e um tipo devolvido. As regras de tipos para os parâmetros e para o tipo devolvido seguem a tua intuição e podes contar com o compilador para te dar orientações detalhadas.
  • Nas operações binárias, o primeiro parâmetro recebe o argumento da esquerda da operação.
  • Os operadores têm uma assinatura composta por dois parâmetros (no caso das operações binárias) e um tipo devolvido, ou por um único parâmetro e um tipo devolvido, no caso dos operadores unários.
  • Nos operadores binários, um dos tipos dos parâmetros tem de ser o da classe onde o operador é declarado.
  • No caso das conversões de tipo, ou o parâmetro ou o tipo devolvido tem de ser o tipo da classe onde o operador é declarado.
  • Nos operadores de incremento e de decremento, o parâmetro e o tipo devolvido têm de ser os da classe onde o operador é declarado.

Exemplos de sintaxe:

struct Point
{
    decimal x;
    decimal y;

    public static bool operator ==(Point pt, Point ptOther)
    {
        return pt.x == ptOther.x && pt.y == ptOther.y;
    }

    public static bool operator !=(Point pt, Point ptOther)
    {
        return !(pt == ptOther);
    }

    public static Point operator *(Point pt, decimal scale)
    {
        var ptNew = new Point();
        ptNew.x = pt.x * scale;
        ptNew.y = pt.y * scale;
        return ptNew;
    }

    public static implicit operator Point((decimal x, decimal y) xy)
    {
        var pt = new Point();
        pt.x = xy.x;
        pt.y = xy.y;
        return pt;
    }

    public static explicit operator (decimal x, decimal y)(Point pt)
    {
        return (pt.x, pt.y);
    }
}

Muitas vezes, é produtivo implementar um método Equals() e chamá-lo a partir do operador ==. Da mesma forma, para as comparações podes implementar a interface IComparable. Em ambos os casos, matas dois coelhos com pouco mais do que uma cajadada.

Convém notar que não podes criar operadores a partir de símbolos que não façam parte do conjunto padrão de operadores. Só podes usar símbolos já existentes para as operações em que a documentação especifica que podem ser sobrecarregadas. Os operadores que podem ser sobrecarregados estão listados aqui.

Repara que a ordem dos parâmetros é importante quando estes têm tipos diferentes. No código de exemplo acima, pt * 10m é uma expressão válida, enquanto 10m * pt não compila.

Referência

Esta documentação de sobrecarga de operadores detalha a sintaxe.

Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Sobrecarga de operadores

A prática está bloqueada

Desbloqueia mais 1 exercício para praticares Sobrecarga de operadores