.NET - Apresentando e usando Métodos Genéricos (C#) - I
Neste artigo vou apresentar os conceitos e mostrar como podemos usar métodos genéricos na linguagem C#. |
O que são métodos genéricos ?
Um método genérico é um método que é declarado com parâmetros de tipo.
Os métodos tradicionais trabalham com parâmetros e retornos fortemente tipados, ou seja, a todo momento conhecemos os tipos concretos dos argumentos que recebemos e dos valores que retornamos. |
Assim, métodos genéricos têm parâmetros de tipo e proporcionam uma maneira de
parametrizar os tipos utilizados em um método.
Isto significa que você pode fornecer uma implementação e pode chamar o método
com tipos diferentes.
Métodos genéricos são uma forma poderosa de fornecer segurança de tipo e ainda
criar métodos flexíveis que suportam vários tipos.
A ideia por trás de um método genérico é simples:
um método genérico aceita parâmetros e
retorna valores de uma gama de diferentes tipos.
Por isso, ele é chamado genérico.
A sintaxe usada para criar métodos genéricos pode parecer a primeira vista um
tanto incomum. A forma de sintaxe para a declaração usa os caracteres <T>
após o nome do método, mas antes da lista de parâmetro formal.
Nota: Todos os exemplos foram feitos no Visual Studio Express 2013 for Windows desktop.
Vejamos um exemplo:
static void Trocar<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
|
Neste código temos a declaração do método genérico Trocar<T> que vai receber dois argumentos de quaisquer tipo e realizar a troca de valores entre os argumentos recebidos.
Podemos usar este método da seguinte forma:
using System;
namespace MetodosGenericos
{
class Program
{
static void Main(string[] args)
{
int a = 10;
int b = 20;
Trocar<int>(ref a, ref b);
Console.WriteLine(a + " " + b);
Console.ReadKey();
string x = "primeiro";
string y = "segundo";
Trocar<string>(ref x, ref y);
Console.WriteLine(x + " " + y);
Console.ReadKey();
}
static void Trocar<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
}
|
Note que procuramos representar no código uma ideia conceitual do tipo : "Meu método vai receber dois objetos de um tipo T qualquer e vai trocar os valores dos objetos"
Vamos mostrar outro exemplo de método genérico.
Suponha que agora eu quero representar via código a seguinte ideia conceitual : "Meu método vai receber dois objetos de um tipo T que implemente a interface IComparable e vai retornar o maior deles"
public T Maximo<T>(T valor1, T valor2) where T : IComparable
{
if (valor1.CompareTo(valor2) > 0) return valor1;
return valor2;
}
|
O método genérico Maximo<T> vai processar qualquer tipo T. Os parâmetros de entrada também são do tipo T e o retorno também e do tipo T.
A seguir temos um exemplo de como usar o método genérico criado acima:
using System;
namespace MetodosGenericos
{
class Program
{
static void Main(string[] args)
{
string maiorString = Maximo("Macoratti", "Jefferson");
int maiorInteiro = Maximo(2, 99);
double maiorDouble = Maximo(445.98, 98.65);
Console.WriteLine("Maior String = {0} ", maiorString);
Console.WriteLine("Maior Inteiro = {0} ", maiorInteiro);
Console.WriteLine("Maior Double = {0} ", maiorDouble);
Console.ReadKey();
}
static public T Maximo<T>(T valor1, T valor2) where T : IComparable
{
if (valor1.CompareTo(valor2) > 0) return valor1;
return valor2;
}
}
}
|
|
Neste exemplo observe que temos uma restrição no método que diz que o tipo T deve implementar a interface IComparable().
Usando essa linha de raciocínio existem vários tipos de restrições que podem ser utilizadas para limitar os tipos permitidos para os nossos métodos parametrizados. Abaixo temos algumas delas:
Where T: struct, indica que o argumento deve ser um tipo de valor.
Where T: class, indica que T deve ser um tipo de referência.
Where T: new(), obriga que o tipo T tenha um construtor público sem parâmetros;
Where T: nomeClasse, indica que o argumento deve herdar ou ser desse tipo.
Where T: nomeInterface, o argumento deve implementar a interface indicada.
Where T1: T2, T1 indica que o argumento T1 deve ser igual ou herdar o tipo, também argumento do método, T2.
Para concluir vejamos agora um exemplo um pouco mais complexo. O método genérico CriaLista, aplicável a qualquer classe, retorna uma lista genérica (List <T>) do tipo parametrizado do método, inicialmente preenchida com os argumentos (variáveis) que são fornecidos:
public List<T> CriaLista<T>(params T[] pars)
{
List<T> lista = new List<T>();
foreach (T elem in pars)
{
lista.Add(elem);
}
return lista;
}
|
A seguir vamos usar este método:
using System;
using System.Collections.Generic;
namespace MetodosGenericos
{
class Program
{
static void Main(string[] args)
{
List<int> numeros = CriaLista<int>(1, 2, 3, 4, 6, 7);
List<string> nomes = CriaLista<string>("Macoratti", "Jefferson", "Miriam", "Janice");
foreach(int numero in numeros)
{
Console.WriteLine(numero + " ");
}
Console.ReadKey();
foreach (string nome in nomes)
{
Console.WriteLine(nome + " ");
}
Console.ReadKey();
}
static public List<T> CriaLista<T>(params T[] pars)
{
List<T> lista = new List<T>();
foreach (T elem in pars)
{
lista.Add(elem);
}
return lista;
}
}
}
|
|
Pegue o projeto completo aqui: MetodosGenericosCSharp.zip
Por isso também damos, sem cessar, graças a Deus, pois, havendo recebido de nós
a palavra da pregação de Deus, a recebestes, não como palavra de homens, mas
(segundo é, na verdade), como palavra de Deus, a qual também opera em vós, os
que crestes.
1 Tessalonicenses 2:13
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
C# - Classes Abstratas, Interface e Polimorfismo - Macoratti ...