Generics in .NET (Genéricos no .NET)Generics in .NET

Os genéricos permitem que você personalize um método, uma classe, uma estrutura ou uma interface para o tipo exato de dados no qual ele atua.Generics let you tailor a method, class, structure, or interface to the precise data type it acts upon. Por exemplo, em vez de usar a classe Hashtable, que permite que as chaves e os valores sejam de qualquer tipo, você pode usar a classe genérica Dictionary<TKey,TValue> e especificar o tipo permitido para a chave e o tipo permitido para o valor.For example, instead of using the Hashtable class, which allows keys and values to be of any type, you can use the Dictionary<TKey,TValue> generic class and specify the type allowed for the key and the type allowed for the value. Entre os benefícios de genéricos estão maior reutilização de códigos e segurança de tipos.Among the benefits of generics are increased code reusability and type safety.

Este tópico fornece uma visão geral de genéricos no .NET e um resumo de tipos ou métodos genéricos.This topic provides an overview of generics in .NET and a summary of generic types or methods. Ele contém as seguintes seções:It contains the following sections:

Definindo e usando genéricosDefining and Using Generics

Genéricos são classes, estruturas, interfaces e métodos que possuem espaços reservados (parâmetros de tipo) para um ou mais dos tipos que eles armazenam ou usam.Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. Uma classe de coleção genérica pode usar um parâmetro de tipo como um espaço reservado para o tipo de objetos que ela armazena; os parâmetros de tipo aparecem como os tipos de seus campos e os tipos de parâmetro de seus métodos.A generic collection class might use a type parameter as a placeholder for the type of objects that it stores; the type parameters appear as the types of its fields and the parameter types of its methods. Um método genérico pode usar seu parâmetro de tipo como o tipo de seu valor de retorno ou como o tipo de um de seus parâmetros formais.A generic method might use its type parameter as the type of its return value or as the type of one of its formal parameters. O código a seguir ilustra uma definição de classe genérica simples.The following code illustrates a simple generic class definition.

generic<typename T>
public ref class Generics
{
public:
    T Field;
};
public class Generic<T>
{
    public T Field;
}
Public Class Generic(Of T)
    Public Field As T

End Class

Quando você cria uma instância de uma classe genérica, pode especificar os tipos reais para substituir os parâmetros de tipo.When you create an instance of a generic class, you specify the actual types to substitute for the type parameters. Isso estabelece uma nova classe genérica, conhecida como uma classe genérica construída, com seus tipos escolhidos substituídos em todos os locais em que aparecem os parâmetros de tipo.This establishes a new generic class, referred to as a constructed generic class, with your chosen types substituted everywhere that the type parameters appear. O resultado é uma classe fortemente tipada que é personalizada para sua escolha de tipos, como mostra o código a seguir.The result is a type-safe class that is tailored to your choice of types, as the following code illustrates.

static void Main()
{
    Generics<String^>^ g = gcnew Generics<String^>();
    g->Field = "A string";
    //...
    Console::WriteLine("Generics.Field           = \"{0}\"", g->Field);
    Console::WriteLine("Generics.Field.GetType() = {0}", g->Field->GetType()->FullName);
}
public static void Main()
{
    Generic<string> g = new Generic<string>();
    g.Field = "A string";
    //...
    Console.WriteLine("Generic.Field           = \"{0}\"", g.Field);
    Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}
Public Shared Sub Main()
    Dim g As New Generic(Of String)
    g.Field = "A string"
    '...
    Console.WriteLine("Generic.Field           = ""{0}""", g.Field)
    Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub

Terminologia de genéricosGenerics terminology

Os seguintes termos são usados para discutir genéricos no .NET:The following terms are used to discuss generics in .NET:

  • A definição de tipo genérico é uma classe, estrutura ou declaração de interface que funciona como um modelo, com espaços reservados para os tipos que ela pode conter ou usar.A generic type definition is a class, structure, or interface declaration that functions as a template, with placeholders for the types that it can contain or use. Por exemplo, a classe System.Collections.Generic.Dictionary<TKey,TValue> pode conter dois tipos: chaves e valores.For example, the System.Collections.Generic.Dictionary<TKey,TValue> class can contain two types: keys and values. Como uma definição de tipo genérico é apenas um modelo, não é possível criar instâncias de uma classe, estrutura ou interface que seja uma definição de tipo genérico.Because a generic type definition is only a template, you cannot create instances of a class, structure, or interface that is a generic type definition.

  • Parâmetros de tipo genérico ou parâmetros de tipo são os espaços reservados em uma definição de método ou de tipo genérico.Generic type parameters, or type parameters, are the placeholders in a generic type or method definition. O tipo genérico System.Collections.Generic.Dictionary<TKey,TValue> tem dois parâmetros de tipo, TKey e TValue, que representam os tipos de suas chaves e valores.The System.Collections.Generic.Dictionary<TKey,TValue> generic type has two type parameters, TKey and TValue, that represent the types of its keys and values.

  • Um tipo genérico construído ou um tipo construído é o resultado de especificação de tipos para os parâmetros de tipo genérico de uma definição de tipo genérico.A constructed generic type, or constructed type, is the result of specifying types for the generic type parameters of a generic type definition.

  • Um argumento de tipo genérico é qualquer tipo que seja substituído por um parâmetro de tipo genérico.A generic type argument is any type that is substituted for a generic type parameter.

  • O termo geral tipo genérico inclui definições de tipo genérico e de tipos construídos.The general term generic type includes both constructed types and generic type definitions.

  • Covariância e contravariância de parâmetros de tipo genérico permitem que você use tipos genéricos construídos cujos argumentos de tipo sejam mais derivados (covariância) ou menos derivados (contravariância) de um tipo construído de destino.Covariance and contravariance of generic type parameters enable you to use constructed generic types whose type arguments are more derived (covariance) or less derived (contravariance) than a target constructed type. A covariância e a contravariância são referidas coletivamente como variância.Covariance and contravariance are collectively referred to as variance. Para obter mais informações, consulte Covariância e contravariância.For more information, see Covariance and Contravariance.

  • Restrições são limites colocados em parâmetros de tipo genérico.Constraints are limits placed on generic type parameters. Por exemplo, você pode limitar um parâmetro de tipo a tipos que implementam a interface genérica System.Collections.Generic.IComparer<T>, para garantir que instâncias do tipo possam ser classificadas.For example, you might limit a type parameter to types that implement the System.Collections.Generic.IComparer<T> generic interface, to ensure that instances of the type can be ordered. Você também pode restringir parâmetros de tipo a tipos que tenham uma determinada classe base, que tenham um construtor padrão ou que sejam tipos de referência ou tipos de valor.You can also constrain type parameters to types that have a particular base class, that have a default constructor, or that are reference types or value types. Os usuários do tipo genérico não podem substituir argumentos de tipo que não satisfaçam as restrições.Users of the generic type cannot substitute type arguments that do not satisfy the constraints.

  • A definição de método genérico é um método com duas listas de parâmetros: uma lista de parâmetros de tipo genérico e uma lista de parâmetros formais.A generic method definition is a method with two parameter lists: a list of generic type parameters and a list of formal parameters. Os parâmetros de tipo podem aparecer como o tipo de retorno ou como os tipos de parâmetros formais, como mostra o código a seguir.Type parameters can appear as the return type or as the types of the formal parameters, as the following code shows.

generic<typename T>
T Generic(T arg)
{
    T temp = arg;
    //...
    return temp;
}
T Generic<T>(T arg)
{
    T temp = arg;
    //...
    return temp;
}
Function Generic(Of T)(ByVal arg As T) As T
    Dim temp As T = arg
    '...
    Return temp
End Function

Métodos genéricos podem aparecer em tipos genéricos ou não genéricos.Generic methods can appear on generic or nongeneric types. É importante observar que um método não é genérico apenas porque ele pertence a um tipo genérico ou até mesmo porque possui parâmetros formais cujos tipos sejam os parâmetros genéricos do tipo de delimitador.It is important to note that a method is not generic just because it belongs to a generic type, or even because it has formal parameters whose types are the generic parameters of the enclosing type. Um método é genérico somente se ele tiver sua própria lista de parâmetros de tipo.A method is generic only if it has its own list of type parameters. No código a seguir, somente o método G é genérico.In the following code, only method G is generic.

ref class A
{
    generic<typename T>
    T G(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
};
generic<typename T>
ref class Generic
{
    T M(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
};
class A
{
    T G<T>(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
class Generic<T>
{
    T M(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
Class A
    Function G(Of T)(ByVal arg As T) As T
        Dim temp As T = arg
        '...
        Return temp
    End Function
End Class
Class Generic(Of T)
    Function M(ByVal arg As T) As T
        Dim temp As T = arg
        '...
        Return temp
    End Function
End Class

Voltar ao inícioBack to top

Vantagens e desvantagens de genéricosAdvantages and disadvantages of generics

Há muitas vantagens no uso de coleções e delegados genéricos:There are many advantages to using generic collections and delegates:

  • Segurança de tipo.Type safety. Genéricos deslocam a carga de segurança de tipos do seu local até o compilador.Generics shift the burden of type safety from you to the compiler. Não é necessário escrever código para testar o tipo de dados correto, pois isso é aplicado no tempo de compilação.There is no need to write code to test for the correct data type because it is enforced at compile time. A necessidade de conversão de tipos e a possibilidade de erros de tempo de execução são reduzidas.The need for type casting and the possibility of run-time errors are reduced.

  • Menos código e código que seja reutilizado com mais facilidade.Less code and code is more easily reused. Não é necessário herdar de um tipo base e substituir membros.There is no need to inherit from a base type and override members. Por exemplo, o LinkedList<T> está pronto para uso imediato.For example, the LinkedList<T> is ready for immediate use. Por exemplo, você pode criar uma lista vinculada de cadeias de caracteres com a seguinte declaração de variável:For example, you can create a linked list of strings with the following variable declaration:

    LinkedList<String^>^ llist = gcnew LinkedList<String^>();
    
    LinkedList<string> llist = new LinkedList<string>();
    
    Dim llist As New LinkedList(Of String)()
    
  • Melhor desempenho.Better performance. Tipos de coleções genéricas geralmente executam melhor para armazenar e manipular tipos de valor, pois não é necessário colocar os tipos de valor em caixa.Generic collection types generally perform better for storing and manipulating value types because there is no need to box the value types.

  • Delegados genéricos permitem retornos fortemente tipados sem a necessidade de criar múltiplas classes de delegados.Generic delegates enable type-safe callbacks without the need to create multiple delegate classes. Por exemplo, o delegado genérico Predicate<T> permite criar um método que implementa seus próprios critérios de pesquisa para um tipo específico e usar seu método com método do tipo Array, tais como Find, FindLast e FindAll.For example, the Predicate<T> generic delegate allows you to create a method that implements your own search criteria for a particular type and to use your method with methods of the Array type such as Find, FindLast, and FindAll.

  • Genéricos simplificam o código gerado dinamicamente.Generics streamline dynamically generated code. Quando você usa genéricos com código gerado dinamicamente, não é necessário gerar o tipo.When you use generics with dynamically generated code you do not need to generate the type. Isso aumenta o número de cenários nos quais você pode usar métodos dinâmicos leves, em vez de gerar assemblies inteiros.This increases the number of scenarios in which you can use lightweight dynamic methods instead of generating entire assemblies. Para obter mais informações, consulte Como: definir e executar métodos dinâmicos e DynamicMethod.For more information, see How to: Define and Execute Dynamic Methods and DynamicMethod.

Veja a seguir algumas limitações de genéricos:The following are some limitations of generics:

  • Os tipos genéricos podem ser derivados da maioria das classes base, tais como MarshalByRefObject (e restrições podem ser usadas para exigir que parâmetros do tipo genérico derivem de classes base como MarshalByRefObject).Generic types can be derived from most base classes, such as MarshalByRefObject (and constraints can be used to require that generic type parameters derive from base classes like MarshalByRefObject). No entanto, o .NET Framework.NET Framework não dá suporte para tipos genéricos vinculados a um contexto.However, the .NET Framework.NET Framework does not support context-bound generic types. Um tipo genérico pode ser derivado de ContextBoundObject, mas tentar criar uma instância desse tipo causa uma TypeLoadException.A generic type can be derived from ContextBoundObject, but trying to create an instance of that type causes a TypeLoadException.

  • Enumerações não podem ter parâmetros do tipo genérico.Enumerations cannot have generic type parameters. Uma enumeração pode ser genérica somente incidentalmente (por exemplo, porque ela está aninhada em um tipo genérico que é definido usando Visual Basic, C# ou C++).An enumeration can be generic only incidentally (for example, because it is nested in a generic type that is defined using Visual Basic, C#, or C++). Para saber mais, confira "Enumerações" em Common Type System.For more information, see "Enumerations" in Common Type System.

  • Métodos dinâmicos leves não podem ser genéricos.Lightweight dynamic methods cannot be generic.

  • No Visual Basic, C# e C++, um tipo aninhado que está embutido em um tipo genérico não pode ser instanciado, a menos que os tipos tenham sido atribuídos aos parâmetros de tipo de todos os tipos de delimitadores.In Visual Basic, C#, and C++, a nested type that is enclosed in a generic type cannot be instantiated unless types have been assigned to the type parameters of all enclosing types. Outra maneira de dizer isso é que em reflexão, um tipo aninhado que é definido usando essas linguagens inclui os parâmetros de tipo de todos os seus tipos de delimitadores.Another way of saying this is that in reflection, a nested type that is defined using these languages includes the type parameters of all its enclosing types. Isso permite que os parâmetros de tipos de delimitadores sejam usados nas definições de membro de um tipo aninhado.This allows the type parameters of enclosing types to be used in the member definitions of a nested type. Para obter mais informações, consulte "Tipos aninhados" em MakeGenericType.For more information, see "Nested Types" in MakeGenericType.

    Observação

    Um tipo aninhado que é definido pela emissão do código em um assembly dinâmico ou usando o Ilasm.exe (IL Assembler) não é necessário para incluir parâmetros de tipo de seus tipos de delimitadores; no entanto, se ele não os incluir, os parâmetros de tipo não estarão no escopo na classe aninhada.A nested type that is defined by emitting code in a dynamic assembly or by using the Ilasm.exe (IL Assembler) is not required to include the type parameters of its enclosing types; however, if it does not include them, the type parameters are not in scope in the nested class.

    Para obter mais informações, consulte "Tipos aninhados" em MakeGenericType.For more information, see "Nested Types" in MakeGenericType.

Voltar ao inícioBack to top

Biblioteca de classes e suporte ao idiomaClass Library and Language Support

O .NET fornece várias classes de coleção genérica nos seguintes namespaces:.NET provides a number of generic collection classes in the following namespaces:

Interfaces genéricas para a implementação de comparações de classificação e de igualdade são fornecidas no namespace System, juntamente com tipos de delegados genéricos para manipuladores de eventos, conversões e predicados de pesquisa.Generic interfaces for implementing sort and equality comparisons are provided in the System namespace, along with generic delegate types for event handlers, conversions, and search predicates.

Foi adicionado suporte para genéricos para o namespace System.Reflection para examinar tipos genéricos e métodos genéricos, para System.Reflection.Emit para emitir assemblies dinâmicos que contenham tipos e métodos genéricos e para System.CodeDom para gerar gráficos de origem que incluem genéricos.Support for generics has been added to the System.Reflection namespace for examining generic types and generic methods, to System.Reflection.Emit for emitting dynamic assemblies that contain generic types and methods, and to System.CodeDom for generating source graphs that include generics.

O Common Language Runtime fornece novos opcodes e prefixos para oferecer suporte a tipos genéricos na Microsoft Intermediate Language (MSIL), incluindo Stelem, Ldelem, Unbox_Any, Constrained e Readonly.The common language runtime provides new opcodes and prefixes to support generic types in Microsoft intermediate language (MSIL), including Stelem, Ldelem, Unbox_Any, Constrained, and Readonly.

Visual C++, C# e Visual Basic todos oferecem suporte completo para definir e usar genéricos.Visual C++, C#, and Visual Basic all provide full support for defining and using generics. Para saber mais sobre suporte à linguagem, confira Tipos genéricos no Visual Basic, Introdução aos genéricos e Visão geral dos genéricos no Visual C++.For more information about language support, see Generic Types in Visual Basic, Introduction to Generics, and Overview of Generics in Visual C++.

Voltar ao inícioBack to top

Tipos e genéricos aninhadosNested Types and Generics

Um tipo que é aninhado em um tipo genérico pode depender dos parâmetros de tipo do tipo genérico de delimitador.A type that is nested in a generic type can depend on the type parameters of the enclosing generic type. O Common Language Runtime considera tipos aninhados como genéricos, mesmo que eles não tenham seus próprios parâmetros de tipo genérico.The common language runtime considers nested types to be generic, even if they do not have generic type parameters of their own. Quando você cria uma instância de um tipo aninhado, deverá especificar argumentos de tipo para todos os tipos de delimitadores.When you create an instance of a nested type, you must specify type arguments for all enclosing generic types.

Voltar ao inícioBack to top

TítuloTitle DescriçãoDescription
Coleções genéricas no .NETGeneric Collections in .NET Descreve as classes de coleção genérica e outros tipos genéricos no .NET.Describes generic collection classes and other generic types in .NET.
Delegados genéricos para manipulação de matrizes e listasGeneric Delegates for Manipulating Arrays and Lists Descreve delegados genéricos para conversões, predicados de pesquisa e ações a serem tomadas nos elementos de uma matriz ou coleção.Describes generic delegates for conversions, search predicates, and actions to be taken on elements of an array or collection.
Interfaces genéricasGeneric Interfaces Descreve interfaces genéricas que fornecem funcionalidade comum entre famílias de tipos genéricos.Describes generic interfaces that provide common functionality across families of generic types.
Covariância e ContravariânciaCovariance and Contravariance Descreve covariância e contravariância em parâmetros de tipo genérico.Describes covariance and contravariance in generic type parameters.
Tipos de Coleção de Uso ComumCommonly Used Collection Types Fornece informações de resumo sobre as características e os cenários de uso dos tipos de coleção no .NET, incluindo tipos genéricos.Provides summary information about the characteristics and usage scenarios of the collection types in .NET, including generic types.
Quando Usar Coleções GenéricasWhen to Use Generic Collections Descreve regras gerais para determinar quando usar tipos de coleção genérica.Describes general rules for determining when to use generic collection types.
Como definir um tipo genérico com a emissão de reflexãoHow to: Define a Generic Type with Reflection Emit Explica como gerar assemblies dinâmicos que incluem tipos e métodos genéricos.Explains how to generate dynamic assemblies that include generic types and methods.
Tipos genéricos no Visual BasicGeneric Types in Visual Basic Descreve o recurso genérico para usuários do Visual Basic, incluindo tópicos de instruções para uso e definição de tipos genéricos.Describes the generics feature for Visual Basic users, including how-to topics for using and defining generic types.
Introdução aos genéricosIntroduction to Generics Fornece uma visão geral da definição e do uso de tipos genéricos para usuários do C#.Provides an overview of defining and using generic types for C# users.
Visão geral de genéricos no Visual C++Overview of Generics in Visual C++ Descreve o recurso de genéricos para usuários do C++, incluindo as diferenças entre genéricos e modelos.Describes the generics feature for C++ users, including the differences between generics and templates.

ReferênciaReference

System.Collections.Generic

System.Collections.ObjectModel

System.Reflection.Emit.OpCodes

Voltar ao inícioBack to top