C# - Sobrecarga de operadores (Operator Overloading)
Sobrecarga (overloading) de operadores !!!
Meu Deus, o que vem a ser isso ????
Se você esta vindo de uma linguagem procedural como Clipper, Dbase , Basic, Cobol, etc. ou se esta começando agora tendo o C# como sua primeira linguagem de programação, pode estranhar o termo. Mas é apenas uma questão de prática.
Sobrecarga (Overload) é a habilidade de poder definir diversas propriedades, métodos ou procedimentos em uma classe com o mesmo nome mas parâmetros diferentes.
Você entendeu ?
Bem, vou ser mais claro.
Se você criar dois procedimentos em seu aplicativo com o mesmo nome e com parâmetros diferentes estará usando sobrecarga.
Você deve estar se perguntando: "Como posso criar dois procedimentos com o mesmo nome ? Como vou diferenciá-los ? ". Garoto 'experto' você !!!
Você vai diferenciar os métodos/procedimentos pela lista de parâmetros que eles vão possuir , isto é , os métodos/procedimentos terão parâmetros diferentes. Vou dar um exemplo :
Suponha que voce precise criar uma classe com um método que retorne o valor da área de um quadrado , só que este método vai poder aceitar como parâmetro uma string ou um número:
public double CalculaArea(double lado) { return lado * lado; } |
public double CalculaArea(string lado) { double ld = 0; ld = Convert.ToDouble(lado); return ld * ld; } |
Aqui temos dois métodos com o mesmo nome - CalculaArea - mas que possuem parâmetros diferentes (tipo de dados diferentes) que fornecem o mesmo resultado.
Pois bem, podemos fazer a mesma coisa para operadores na linguagem C#.
A linguagem C#, assim como muitas linguagens orientadas a objetos, permitem a sobrecarga de operadores, ou seja a capacidade de redefinir os operadores de uma classe.
Nem todos os operadores podem ser sobrecarregados, e existem restrições relativas a quando certos operadores podem ser sobrecarregados, como a definição dos operadores == e /=.
Através da sobrecarga de operadores podemos realizar operações complexas através de argumentos de funções e isso nos permite escrever um código muito mais intuitivo e legível.
Para modificar um operador na linguagem C# usamos a seguinte sintaxe:
[modificadores*][type] operator [operator] (parâmetros){( )}
Os operadores uniários recebem somente um parâmetro e os operadores binários recebem dois parâmetros, sendo que em cada caso um dos parâmetros deve ser do tipo da classe que esta redefinindo o operador.
public static ret-type operator op(parameter-type operand) { } |
public static ret-type operator op(parameter-type operand1, parameter-type operand1) { } |
Operador Uniário | Operador Binário |
Obs: Os operadores redefinidos devem ser public static
Vejamos um exemplo prático onde iremos realizar a sobrecarga do operador ++.
Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo Console Application com o nome SobreCargaOperadores;
A seguir defina o seguinte código na classe Program.cs:
using System; namespace SobrecargarOperadores { class Program { static void Main(string[] args) { Calculo i = new Calculo(100, 200, 300); Calculo j = new Calculo(5, 10, 3); i++; i.MostraResultado(); j++; j.MostraResultado(); Console.WriteLine(); } } class Calculo { int a, b, c; public Calculo() { a = b = c = 0; } public Calculo(int x, int y, int z) { a = x; b = y; c = z; } public static Calculo operator ++(Calculo op1) { op1.a++; op1.b++; op1.c++; return op1; } public void MostraResultado() { Console.WriteLine(a + "," + b + "," + c); Console.ReadLine(); } } } |
Aqui criamos a classe Calculo
e redefinimos o operador ++ para realizar o incremento em uma unidade dos argumentos recebidos. Executando o projeto teremos : |
Muito simples,não é mesmo ???
Vamos agora realizar a sobrecarga de
operadores binários para os operadores + , - , / e * (adição,
subtração, divisão e multiplicação.)
No menu File clique em
Add -> Project e a seguir informe o nome OperadoresBInarios;
Defina a seguir o código abaixo na classe Program.cs:
using System; namespace OperadoresBinarios { class Program { static void Main(string[] args) { Calculo i = new Calculo(10, 20, 30); Calculo j = new Calculo(5, 10, 15); Calculo k = new Calculo(); Console.WriteLine("Sobrecarga de Operadores"); Console.WriteLine("i = 10, 20, 30"); Console.WriteLine("j = 5, 10, 15"); Console.WriteLine(); //adição k = i + j; Console.WriteLine("+"); k.MostraResultado(); Console.WriteLine(); //subtração k = i - j; Console.WriteLine("-"); k.MostraResultado(); Console.WriteLine(); //multiplicação k = i * j; Console.WriteLine("*"); k.MostraResultado(); Console.WriteLine(); //divisão k = i / j; Console.WriteLine("/"); k.MostraResultado(); Console.WriteLine(); } } class Calculo { int a, b, c; public Calculo() { a = b = c = 0; } public Calculo(int x, int y, int z) { a = x; b = y; c = z; } public static Calculo operator +(Calculo op1, Calculo op2) { Calculo calc = new Calculo(); calc.a = op1.a + op2.a; calc.b = op1.b + op2.b; calc.c = op1.c + op2.c; return calc; } public static Calculo operator -(Calculo op1, Calculo op2) { Calculo calc = new Calculo(); calc.a = op1.a - op2.a; calc.b = op1.b - op2.b; calc.c = op1.c - op2.c; return calc; } public static Calculo operator *(Calculo op1, Calculo op2) { Calculo calc = new Calculo(); calc.a = op1.a * op2.a; calc.b = op1.b * op2.b; calc.c = op1.c * op2.c; return calc; } public static Calculo operator /(Calculo op1, Calculo op2) { Calculo calc = new Calculo(); calc.a = op1.a / op2.a; calc.b = op1.b / op2.b; calc.c = op1.c / op2.c; return calc; } public void MostraResultado() { Console.WriteLine(a + "," + b + "," + c); Console.ReadLine(); } } } |
Aqui temos a sobrecarga dos
operadores +, -, / e * : Executando o projeto teremos: |
Se os operadores de comparação (==) forem sobrecarregados, essa sobrecarga deve ser feita aos pares, ou seja, se for sobrecarregado o operador == também se deve sobrecarregar o operador !=. O mesmo vale para os operadores < e >, e <= e >=.
Outro fato importante é que se por exemplo, você está sobrecarregando o operador == não pode usar (a == b), (a == null) ou (b == null) para verificar a igualdade de referência dentro da sobrecarga.
Isso resulta em uma chamada para o operador sobrecarregado ==, que é o mesmo que voltar a chamar o operador que você está redefinindo e como resultado há um loop infinito. Use ReferenceEquals ou converta o tipo de Objeto para evitar isso.
E estamos conversados...
Pegue o projeto completo aqui: SobrecargarOperadores.zip
1Ts 5:14
Exortamo-vos também, irmãos, a que admoesteis os insubordinados, consoleis os desanimados, ampareis os fracos e sejais longânimos para com todos.1Ts 5:15
Vede que ninguém dê a outrem mal por mal, mas segui sempre o bem, uns para com os outros, e para com todos.Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
VB .NET e C# - Diferenças entre os Operadores - Macoratti
VB.NET - Novos operadores lógicos - Macoratti
C# - Sobrecarga de operadores - Macoratti
NET - Estruturas x Classes - Macoratti
VB.NET - Novos operadores lógicos - Macoratti
C# - Sintaxe e conceitos básicos - Macoratti
C# - Operadores Lógicos - Macoratti
C# - Conceitos - Operador Ternário - Macoratti