Genéricos no Executar Hora (guia de programação C#)

Quando um tipo genérico ou método é compilado em Microsoft intermediate language (MSIL), ele contém metadados que o identifica como tendo os parâmetros de tipo. Como o MSIL para um tipo genérico é usado difere dependendo se o parâmetro de tipo fornecido é um valor tipo ou tipo de referência.

Quando o primeiro, um tipo genérico é construído com um tipo de valor como um parâmetro, o runtime cria um tipo genérico especializado com o parâmetro fornecido ou substituídos nos locais apropriados na MSIL de parâmetros. Tipos genéricos especializados são criados uma vez para cada tipo de valor exclusivo que é usado como um parâmetro.

Por exemplo, suponha que seu código de programa declarado uma pilha que é construída de inteiros:

Stack<int> stack;

Neste ponto, o tempo de execução gera uma versão especializada da Stack<T> classe que tem o número inteiro substituído apropriadamente para parâmetro. Agora, sempre que o seu código de programa utiliza uma pilha de inteiros, a reutiliza de tempo de execução gerada especializadas Stack<T> classe. No exemplo a seguir, duas instâncias de uma pilha de inteiros são criadas e compartilham uma única instância de Stack<int> código:

Stack<int> stackOne = new Stack<int>();
Stack<int> stackTwo = new Stack<int>();

No entanto, suponha que outro Stack<T> classe com um tipo de valor diferente, como um long ou uma estrutura definida pelo usuário como seu parâmetro é criada em outro ponto no seu código. Como resultado, o tempo de execução gera outra versão do tipo genérico e substitui um long nos locais apropriados na MSIL. Conversões não são mais necessárias porque cada classe genérica especializado nativamente contém o tipo de valor.

Os genéricos funcionam de modo um pouco diferente para tipos de referência. Na primeira vez que um tipo genérico é construído com qualquer tipo de referência, o runtime cria um tipo genérico especializado com referências de objeto que substituirá os parâmetros de MSIL. Em seguida, sempre que um tipo construído é instanciado com um tipo de referência como seu parâmetro, independentemente do tipo é, o runtime reutiliza a criado anteriormente versão especializada do tipo genérico. Isso é possível porque todas as referências são do mesmo tamanho.

Por exemplo, suponha que você tinha dois tipos de referência, um Customer classe e um Order de classe e também, suponha que você criou uma pilha de Customer tipos:

class Customer { }
class Order { }
Stack<Customer> customers;

Neste ponto, o tempo de execução gera uma versão especializada do Stack<T> classe que armazena as referências de objeto que serão preenchidas posteriormente em vez de armazenar dados. Suponha que a próxima linha de código cria uma pilha de outro tipo de referência, que é chamada de Order:

Stack<Order> orders = new Stack<Order>();

Diferentemente com tipos de valor, outro especializado versão do Stack<T> classe não é criada para o Order tipo. Em vez disso, uma instância da versão especializada da Stack<T> classe é criada e o orders variável é definida para referenciar o proprietário. Suponha que você encontrou, em seguida, uma linha de código para criar uma pilha de um Customer tipo:

customers = new Stack<Customer>();

Como ocorre com a utilização anterior a Stack<T> classe criada usando o Order tipo, outra instância do especializado Stack<T> classe é criada. Os ponteiros que nele contidos estão definidos para fazer referência a uma área da memória o tamanho de um Customer tipo. Porque o número de tipos de referência pode variar muito de um programa para programa, o C# implementação de genéricos reduz bastante a quantidade de código, reduzindo a um número de classes especializadas, criado pelo compilador para classes genéricas de tipos de referência.

Além disso, quando uma classe genérica C# é instanciada usando um parâmetro de tipo de referência ou de tipo de valor, reflexão pode consultar em tempo de execução e seu tipo real e o seu parâmetro de tipo podem ser determinadas.

Consulte também

Referência

Introduction to Generics (C# Programming Guide)

System.Collections.Generic

Conceitos

C# Programming Guide

Classes genéricas no .NET Framework