Métodos genéricos (guia de programação em C#)
Um método genérico é um método que é declarado com parâmetros de tipo, da seguinte maneira:
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
O exemplo de código a seguir mostra uma maneira de chamar o método usando int
para o argumento type:
public static void TestSwap()
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
System.Console.WriteLine(a + " " + b);
}
Você também pode omitir o argumento type e o compilador irá inferi-lo. A seguinte chamada para Swap
é equivalente à chamada anterior:
Swap(ref a, ref b);
As mesmas regras para inferência de tipo se aplicam a métodos estáticos e métodos de instância. O compilador pode inferir os parâmetros de tipo com base nos argumentos do método que você passa; ele não pode inferir os parâmetros de tipo somente a partir de uma restrição ou valor de retorno. Portanto, a inferência de tipo não funciona com métodos que não têm parâmetros. A inferência de tipo ocorre em tempo de compilação antes que o compilador tente resolver assinaturas de método sobrecarregadas. O compilador aplica lógica de inferência de tipo a todos os métodos genéricos que compartilham o mesmo nome. Na etapa de resolução de sobrecarga, o compilador inclui apenas os métodos genéricos nos quais a inferência de tipo foi bem-sucedida.
Dentro de uma classe genérica, métodos não genéricos podem acessar os parâmetros de tipo de nível de classe, da seguinte maneira:
class SampleClass<T>
{
void Swap(ref T lhs, ref T rhs) { }
}
Se você definir um método genérico que usa os mesmos parâmetros de tipo que a classe que contém, o compilador gera aviso CS0693 porque dentro do escopo do método, o argumento fornecido para o interno T
oculta o argumento fornecido para o externo T
. Se você precisar da flexibilidade de chamar um método de classe genérico com argumentos de tipo diferentes daqueles fornecidos quando a classe foi instanciada, considere fornecer outro identificador para o parâmetro type do método, conforme mostrado no GenericList2<T>
exemplo a seguir.
class GenericList<T>
{
// CS0693.
void SampleMethod<T>() { }
}
class GenericList2<T>
{
// No warning.
void SampleMethod<U>() { }
}
Use restrições para habilitar operações mais especializadas em parâmetros de tipo em métodos. Esta versão do , agora chamada SwapIfGreater<T>
, só pode ser usada com argumentos de Swap<T>
tipo que implementam IComparable<T>o .
void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
Os métodos genéricos podem ser sobrecarregados em vários parâmetros de tipo. Por exemplo, os seguintes métodos podem estar localizados na mesma classe:
void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }
Você também pode usar o parâmetro type como o tipo de retorno de um método. O exemplo de código a seguir mostra um método que retorna uma matriz do tipo T
:
T[] Swap<T>(T a, T b)
{
return [b, a];
}
Especificação da linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#.