Elementos genéricos en .NETGenerics in .NET

Los genéricos permiten personalizar un método, clase, estructura o interfaz con respecto a los datos precisos sobre los que se actúa.Generics let you tailor a method, class, structure, or interface to the precise data type it acts upon. Por ejemplo, en lugar de utilizar la clase Hashtable , que permite cualquier tipo de clave y valor, puede utilizar la clase genérica Dictionary<TKey,TValue> y especificar el tipo permitido para la clave y el tipo permitido para el 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 las ventajas de los genéricos están una mayor reutilización del código y la seguridad de tipos.Among the benefits of generics are increased code reusability and type safety.

En este tema se proporciona información general sobre los genéricos en .NET, así como un resumen de los métodos o tipos genéricos.This topic provides an overview of generics in .NET and a summary of generic types or methods. Contiene las siguientes secciones:It contains the following sections:

Definición y uso de genéricosDefining and Using Generics

Los genéricos son clases, estructuras, interfaces y métodos que tienen marcadores de posición (parámetros de tipo) para uno o varios de los tipos que almacenan o utilizan.Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. Una clase de colección genérica puede usar un parámetro de tipo como marcador de posición para el tipo de objetos que almacena; los parámetros de tipo aparecen como los tipos de sus campos y los tipos de parámetros de sus 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. Un método genérico puede usar su parámetro de tipo como el tipo de su valor devuelto o como el tipo de uno de sus parámetros formales.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. El código siguiente ilustra una definición de clase genérica simple.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

Cuando cree una instancia de una clase genérica, especifique los tipos reales que hay que sustituir para los parámetros de tipo.When you create an instance of a generic class, you specify the actual types to substitute for the type parameters. Esto establece una nueva clase genérica, a la que se hace referencia como clase genérica construida, con los tipos que elija sustituidos en todas partes en la que aparecen los 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. El resultado es una clase con seguridad de tipos que se adapta a su elección de tipos, como se muestra en el código siguiente.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

Terminología de los genéricosGenerics terminology

Los siguientes términos se utilizan para explicar los genéricos en .NET:The following terms are used to discuss generics in .NET:

  • Una definición de tipo genérico es una clase, estructura o declaración de interfaz que funciona como una plantilla, con marcadores de posición para los tipos que puede contener o utilizar.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 ejemplo, la clase System.Collections.Generic.Dictionary<TKey,TValue> puede contener dos tipos: claves y valores.For example, the System.Collections.Generic.Dictionary<TKey,TValue> class can contain two types: keys and values. Dado que una definición de tipo genérico es solo una plantilla, no se pueden crear instancias de una clase, estructura o interfaz que sea una definición 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.

  • Losparámetros de tipo genérico, o parámetros de tipo, son los marcadores de posición en una definición de método o tipo genérico.Generic type parameters, or type parameters, are the placeholders in a generic type or method definition. El tipo genérico System.Collections.Generic.Dictionary<TKey,TValue> tiene dos parámetros de tipo, TKey y TValue, que representan los tipos de sus claves y 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.

  • Un tipo genérico construido, o tipo construido, es el resultado de especificar los tipos para los parámetros de tipo genérico de una definición 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.

  • Un argumento de tipo genérico es cualquier tipo que se sustituye por un parámetro de tipo genérico.A generic type argument is any type that is substituted for a generic type parameter.

  • El término general tipo genérico incluye tanto tipos construidos como definiciones de tipo genérico.The general term generic type includes both constructed types and generic type definitions.

  • La covarianza y contravarianza de parámetros de tipo genérico permite usar tipos genéricos construidos, cuyos argumentos de tipo están más derivados (covarianza) o menos derivados (contravarianza) que un tipo construido 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. La covarianza y la contravarianza se denominan colectivamente varianza.Covariance and contravariance are collectively referred to as variance. Para obtener más información, vea Covarianza y contravarianza.For more information, see Covariance and Contravariance.

  • Lasrestricciones son límites colocados en parámetros de tipo genérico.Constraints are limits placed on generic type parameters. Por ejemplo, puede limitar un parámetro de tipo a tipos que implementan la interfaz genérica System.Collections.Generic.IComparer<T> para asegurarse de que se pueden ordenar las instancias del tipo.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. También puede restringir los parámetros de tipo a tipos que tienen una clase base concreta, un constructor sin parámetros o que son tipos de referencia o tipos de valor.You can also constrain type parameters to types that have a particular base class, that have a parameterless constructor, or that are reference types or value types. Los usuarios del tipo genérico no pueden sustituir los argumentos de tipo que no cumplen con las restricciones.Users of the generic type cannot substitute type arguments that do not satisfy the constraints.

  • Una definición de método genérico es un método con dos listas de parámetros: una lista de parámetros de tipo genérico y una lista de parámetros formales.A generic method definition is a method with two parameter lists: a list of generic type parameters and a list of formal parameters. Los parámetros de tipo pueden aparecer como el tipo de valor devuelto o como los tipos de los parámetros formales, como se muestra en el siguiente código.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

Los métodos genéricos pueden aparecer en tipos genéricos o no genéricos.Generic methods can appear on generic or nongeneric types. Es importante tener en cuenta que un método no es genérico solo porque pertenezca a un tipo genérico, ni siquiera porque tenga parámetros formales cuyos tipos sean los parámetros genéricos del tipo envolvente.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. Un método solo es genérico si tiene su propia lista de parámetros de tipo.A method is generic only if it has its own list of type parameters. En el siguiente código, solo es genérico el método G .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

Volver al principioBack to top

Ventajas y desventajas de los genéricosAdvantages and disadvantages of generics

Usar delegados y colecciones genéricas ofrece muchas ventajas:There are many advantages to using generic collections and delegates:

  • Seguridad de tipos.Type safety. Los genéricos trasladan al compilador la carga de la seguridad de tipos.Generics shift the burden of type safety from you to the compiler. No es necesario escribir código para comprobar el tipo de datos correcto porque se hace en tiempo de compilación.There is no need to write code to test for the correct data type because it is enforced at compile time. Se reduce la necesidad de conversión de tipos y la posibilidad de errores en tiempo de ejecución.The need for type casting and the possibility of run-time errors are reduced.

  • Menos código que, además, se reutiliza más fácilmente.Less code and code is more easily reused. No es necesario heredar de un tipo base y reemplazar a los miembros.There is no need to inherit from a base type and override members. Por ejemplo, LinkedList<T> está listo para su uso inmediato.For example, the LinkedList<T> is ready for immediate use. Por ejemplo, puede crear una lista vinculada de cadenas con la siguiente declaración de variable: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)()
    
  • Mejor rendimiento.Better performance. Los tipos de colección genéricos suelen comportarse mejor en el almacenamiento y manipulación de tipos de valor porque no es necesario realizar una conversión boxing de los tipos de valor.Generic collection types generally perform better for storing and manipulating value types because there is no need to box the value types.

  • Los delegados genéricos permiten devoluciones de llamada con seguridad de tipos sin necesidad de crear varias clases de delegado.Generic delegates enable type-safe callbacks without the need to create multiple delegate classes. Por ejemplo, el delegado genérico Predicate<T> le permite crear un método que implementa sus propios criterios de búsqueda para un tipo concreto y utilizar su método con métodos del tipo Array , como Find, FindLasty 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.

  • Los genéricos optimizan el código generado dinámicamente.Generics streamline dynamically generated code. Cuando se utilizan genéricos con código generado dinámicamente, no es necesario generar el tipo.When you use generics with dynamically generated code you do not need to generate the type. Esto aumenta el número de escenarios en los que puede utilizar métodos dinámicos ligeros en lugar de generar ensamblados completos.This increases the number of scenarios in which you can use lightweight dynamic methods instead of generating entire assemblies. Para obtener más información, vea Cómo: Definir y ejecutar métodos dinámicos y DynamicMethod.For more information, see How to: Define and Execute Dynamic Methods and DynamicMethod.

Las siguientes son algunas limitaciones de los genéricos:The following are some limitations of generics:

  • Los tipos genéricos pueden derivarse de la mayoría de las clases base, como MarshalByRefObject (y pueden utilizarse restricciones para exigir que los parámetros de tipo genérico se deriven de clases 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). Sin embargo, .NET Framework no admite los tipos genéricos enlazados a un contexto.However, the .NET Framework does not support context-bound generic types. Un tipo genérico puede derivarse de ContextBoundObject, pero al intentar crear una instancia de dicho tipo, se genera una TypeLoadException.A generic type can be derived from ContextBoundObject, but trying to create an instance of that type causes a TypeLoadException.

  • Las enumeraciones no pueden tener parámetros de tipo genérico.Enumerations cannot have generic type parameters. Una enumeración solo puede ser genérica a propósito (por ejemplo, porque está anidada en un tipo genérico definido mediante Visual Basic, C# o 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 más información, vea "Enumeraciones" en Common Type System.For more information, see "Enumerations" in Common Type System.

  • Los métodos dinámicos ligeros no pueden ser genéricos.Lightweight dynamic methods cannot be generic.

  • En Visual Basic, C# y C++, no se pueden crear instancias de un tipo anidado incluido en un tipo genérico, a menos que los tipos se hayan asignado a los parámetros de tipo de todos los tipos envolventes.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. Dicho de otro modo: en la reflexión, un tipo anidado definido mediante estos lenguajes incluye los parámetros de tipo de todos sus tipos envolventes.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. Esto permite que los parámetros de tipo de tipos envolventes se usen en las definiciones de miembro de un tipo anidado.This allows the type parameters of enclosing types to be used in the member definitions of a nested type. Para obtener más información, vea “Tipos anidados” en MakeGenericType.For more information, see "Nested Types" in MakeGenericType.

    Nota

    Un tipo anidado definido mediante la emisión de código en un ensamblado dinámico o mediante el uso de Ilasm.exe (Ensamblado de IL) no necesita incluir los parámetros de tipo de sus tipos envolventes. Sin embargo, si no los incluye, los parámetros de tipo no estarán en el ámbito de la clase anidada.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 obtener más información, vea “Tipos anidados” en MakeGenericType.For more information, see "Nested Types" in MakeGenericType.

Volver al principioBack to top

Biblioteca de clases y lenguajes compatiblesClass Library and Language Support

.NET ofrece una serie de clases de colección genérica en los espacios de nombres siguientes:.NET provides a number of generic collection classes in the following namespaces:

Las interfaces genéricas para implementar comparaciones de orden e igualdad se proporcionan en el espacio de nombres System , junto con los tipos de delegado genérico para controladores de eventos, conversiones y predicados de búsqueda.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.

Se ha agregado compatibilidad con genéricos a los siguientes espacios de nombres: a System.Reflection para examinar tipos y métodos genéricos; a System.Reflection.Emit para emitir ensamblados dinámicos que contengan tipos y métodos genéricos; y a System.CodeDom para generar gráficos de origen que incluyan 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.

Common language runtime proporciona nuevos opcode y prefijos para admitir tipos genéricos en el lenguaje intermedio de Microsoft (MSIL), incluidos Stelem, Ldelem, Unbox_Any, Constrainedy 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# y Visual Basic proporcionan compatibilidad completa para definir y utilizar genéricos.Visual C++, C#, and Visual Basic all provide full support for defining and using generics. Para más información sobre la compatibilidad de lenguaje, consulte Tipos genéricos en Visual Basic, Introducción a los genéricos e Información general sobre genéricos en Visual C++.For more information about language support, see Generic Types in Visual Basic, Introduction to Generics, and Overview of Generics in Visual C++.

Volver al principioBack to top

Genéricos y tipos anidadosNested Types and Generics

Un tipo que está anidado en un tipo genérico puede depender de los parámetros de tipo del tipo genérico envolvente.A type that is nested in a generic type can depend on the type parameters of the enclosing generic type. Common language runtime considera que los tipos anidados son genéricos, aunque no tengan sus propios 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. Cuando cree una instancia de un tipo anidado, especifique los argumentos de tipo para todos los tipos genéricos envolventes.When you create an instance of a nested type, you must specify type arguments for all enclosing generic types.

Volver al principioBack to top

TitleTitle DESCRIPCIÓNDescription
Colecciones genéricas en .NETGeneric Collections in .NET Describe las clases de colección genérica y otros tipos genéricos en .NET.Describes generic collection classes and other generic types in .NET.
Delegados genéricos para manipular matrices y listasGeneric Delegates for Manipulating Arrays and Lists Describe los delegados genéricos para conversiones, predicados de búsqueda y acciones realizadas en los elementos de una matriz o colección.Describes generic delegates for conversions, search predicates, and actions to be taken on elements of an array or collection.
Interfaces genéricasGeneric Interfaces Describe las interfaces genéricas que proporcionan funcionalidad común entre las familias de tipos genéricos.Describes generic interfaces that provide common functionality across families of generic types.
Covarianza y contravarianzaCovariance and Contravariance Describe la covarianza y la contravarianza en los parámetros de tipo genérico.Describes covariance and contravariance in generic type parameters.
Tipos de colección utilizados normalmenteCommonly Used Collection Types Proporciona información de resumen sobre las características y escenarios de uso de los tipos de colección en .NET, incluidos los tipos genéricos.Provides summary information about the characteristics and usage scenarios of the collection types in .NET, including generic types.
Cuándo utilizar colecciones genéricasWhen to Use Generic Collections Describe las reglas generales para determinar cuándo utilizar los tipos de colección genéricos.Describes general rules for determining when to use generic collection types.
Cómo: Definir un tipo genérico con emisión de reflexiónHow to: Define a Generic Type with Reflection Emit Explica cómo generar ensamblados dinámicos que incluyan métodos y tipos genéricos.Explains how to generate dynamic assemblies that include generic types and methods.
Generic Types in Visual BasicGeneric Types in Visual Basic Describe los genéricos a los usuarios de Visual Basic e incluye temas sobre el uso y la definición de tipos genéricos.Describes the generics feature for Visual Basic users, including how-to topics for using and defining generic types.
Introducción a los genéricosIntroduction to Generics Proporciona información general sobre la definición y uso de tipos genéricos para usuarios de C#.Provides an overview of defining and using generic types for C# users.
Información general sobre genéricos en Visual C++Overview of Generics in Visual C++ Describe los genéricos a los usuarios de C++ e incluye las diferencias entre genéricos y plantillas.Describes the generics feature for C++ users, including the differences between generics and templates.

ReferenciaReference

System.Collections.Generic

System.Collections.ObjectModel

System.Reflection.Emit.OpCodes

Volver al principioBack to top