Exportar (0) Imprimir
Expandir todo
Expandir Minimizar
Este artículo proviene de un motor de traducción automática. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original

Type.MakeGenericType (Método)

Sustituye los elementos de una matriz de tipos por los parámetros de tipo de la definición de tipo genérico actual y devuelve un objeto Type que representa el tipo construido resultante.

Espacio de nombres:  System
Ensamblado:  mscorlib (en mscorlib.dll)

public virtual Type MakeGenericType(
	params Type[] typeArguments
)

Parámetros

typeArguments
Tipo: System.Type[]
Matriz de tipos que se va a sustituir por los parámetros del tipo genérico actual.

Valor devuelto

Tipo: System.Type
Objeto Type que representa el tipo construido formado al sustituir los elementos de typeArguments por los parámetros del tipo genérico actual.

ExcepciónCondición
InvalidOperationException

El tipo actual no representa una definición de tipo genérico. Es decir, IsGenericTypeDefinition devuelve false.

ArgumentNullException

typeArguments es null.

O bien

Algún elemento de typeArguments es null.

ArgumentException

El número de elementos de typeArguments no coincide con el número de parámetros de tipo de la definición de tipo genérico actual.

O bien

Algún elemento de typeArguments no satisface las restricciones especificadas para el parámetro de tipo correspondiente del tipo genérico actual.

O bien

typeArguments contiene un elemento que es un tipo de puntero (Type.IsPointer devuelve true), un tipo por referencia (Type.IsByRef devuelve true) o Void.

NotSupportedException

El método invocado no se admite en la clase base. Las clases derivadas deben proporcionar una implementación.

El método MakeGenericType permite escribir código que asigna tipos específicos a los parámetros de tipo de una definición de tipo genérico, por lo que crea un objeto Type que representa un tipo construido determinado. Puede utilizar este objeto Type para crear instancias en tiempo de ejecución del tipo construido.

Los tipos construidos con el método MakeGenericType pueden ser abiertos; es decir, algunos de sus argumentos de tipo pueden ser parámetros de tipo de métodos o tipos genéricos envolventes. Podría utilizar dichos tipos construidos abiertos al emitir ensamblados dinámicos. Por ejemplo, considere las clases Base y Derived en el código siguiente.


public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }


Para generar la clase Derived en un ensamblado dinámico, es necesario construir su tipo base. Para ello, llame al método MakeGenericType en un objeto Type que represente la clase Base y utilice los argumentos de tipo genérico Int32 y el parámetro de tipo V de la clase Derived. Dado que los tipos y los parámetros de tipo genérico se representan mediante objetos Type, se puede pasar al método MakeGenericType una matriz que contenga los dos.

NotaNota

Un tipo construido como Base<int, V> resulta útil al emitir código, pero no se puede llamar al método MakeGenericType en este tipo porque no es una definición de tipo genérico. Para crear un tipo construido cerrado del que se pueden crear instancias, primero llame al método GetGenericTypeDefinition a fin de obtener un objeto Type que represente una definición de tipo genérico y, luego, llame al método MakeGenericType con los argumentos de tipo deseados.

El objeto Type devuelto por el método MakeGenericType es el mismo que el objeto Type que se obtiene al llamar al método GetType del tipo construido resultante o al método GetType de cualquier tipo construido que se haya creado a partir de la misma definición de tipo genérico con el mismo tipo de argumentos.

NotaNota

Una matriz de tipos genéricos no es propiamente un tipo genérico. No se puede llamar al método MakeGenericType en un tipo de matriz como C<T>[] (Dim ac() As C(Of T) en Visual Basic). Si desea construir un tipo genérico cerrado a partir de C<T>[], llame a GetElementType para obtener la definición de tipo genérico C<T>; llame a MakeGenericType en la definición de tipo genérico para crear el tipo construido y, por último, llame al método MakeArrayType en el tipo construido para crear el tipo de matriz. Lo anterior también se aplica a los tipos de puntero y a los tipos ref (ByRef en Visual Basic).

Si desea obtener una lista de las condiciones invariables para términos que se utilizan en la reflexión genérica, vea los comentarios de la propiedad IsGenericType.

Tipos anidados

Si se define un tipo genérico utilizando C# , C++ o Visual Basic, todos sus tipos anidados son genéricos. Esto se cumple incluso cuando los tipos anidados no poseen ningún parámetro de tipo propio, porque los tres lenguajes incluyen los parámetros de tipo de los tipos envolventes en las listas de parámetros de tipo de los tipos anidados. Considere las clases siguientes:


public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}


La lista de parámetros de tipo de la clase anidada Inner tiene dos parámetros de tipo, T y U, siendo el primero el parámetro de tipo de su clase envolvente. De manera similar, la lista de parámetros de tipo de la clase anidada Innermost1 tiene tres parámetros de tipo, T, U y V, proviniendo T y U de sus clases envolventes. La clase anidada Innermost2 tiene dos parámetros de tipo, T y U, que provienen de sus clases envolventes.

Si la lista de parámetros del tipo envolvente tiene más de un parámetro de tipo, todos los parámetros de tipo se incluyen en orden en la lista de parámetros de tipo del tipo anidado.

Para construir un tipo genérico a partir de la definición de tipo genérico para un tipo anidado, llame al método MakeGenericType con la matriz formada al concatenar las matrices de argumentos de todos los tipos envolventes, comenzando por el tipo genérico exterior y finalizando por la matriz de argumentos del tipo anidado si este tiene sus propios parámetros de tipo. Para crear una instancia de Innermost1, llame al método MakeGenericType con una matriz que contiene tres tipos, estar asignado a T, U y V. Para crear una instancia de Innermost2, llame al método MakeGenericType con una matriz que contiene tres dos, estar asignado a T y U.

El lenguaje propaga los parámetros de tipo de los tipos envolventes de esta manera, de modo que puede utilizar los parámetros de tipo de un tipo envolvente para definir los campos de los tipos anidados. De lo contrario, los parámetros de tipo no quedarán dentro del ámbito en los tipos anidados. Es posible definir tipos anidados sin propagar los parámetros de tipo de los tipos envolventes mediante la emisión de código en los ensamblados dinámicos o utilizando Ilasm.exe (Ensamblador de IL). Consideremos el código siguiente para el ensamblador de MSIL:

.class public Outer<T> {
    .class nested public Inner<U> {
        .class nested public Innermost {
        }
    }
}

En este ejemplo, no es posible definir un campo de tipo T o U en la clase Innermost, puesto que esos parámetros de tipo están fuera de ámbito. En el código de ensamblador siguiente se definen clases anidadas que se comportan igual que si estuvieran definidas en C++, Visual Basic y C#:

.class public Outer<T> {
    .class nested public Inner<T, U> {
        .class nested public Innermost<T, U, V> {
        }
    }
}

Puede utilizar Ildasm.exe (Desensamblador de IL) para examinar clases anidadas definidas en los lenguajes de alto nivel y observar este esquema de denominación.

En el ejemplo siguiente se utiliza el método MakeGenericType para crear un tipo construido a partir de la definición de tipo genérico para el tipo Dictionary<TKey, TValue>. El tipo construido representa una colección Dictionary<TKey, TValue> de objetos Test con claves de cadena.


using System;
using System.Reflection;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Create a constructed type from the generic Dictionary type.");

        // Create a type object representing the generic Dictionary 
        // type, by omitting the type arguments (but keeping the 
        // comma that separates them, so the compiler can infer the
        // number of type parameters).      
        Type generic = typeof(Dictionary<,>);
        DisplayTypeInfo(generic);

        // Create an array of types to substitute for the type
        // parameters of Dictionary. The key is of type string, and
        // the type to be contained in the Dictionary is Test.
        Type[] typeArgs = { typeof(string), typeof(Test) };

        // Create a Type object representing the constructed generic
        // type.
        Type constructed = generic.MakeGenericType(typeArgs);
        DisplayTypeInfo(constructed);

        // Compare the type objects obtained above to type objects
        // obtained using typeof() and GetGenericTypeDefinition().
        Console.WriteLine("\r\n--- Compare types obtained by different methods:");

        Type t = typeof(Dictionary<String, Test>);
        Console.WriteLine("\tAre the constructed types equal? {0}", t == constructed);
        Console.WriteLine("\tAre the generic types equal? {0}", 
            t.GetGenericTypeDefinition() == generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);

        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);

        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);

        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test

--- Compare types obtained by different methods:
        Are the constructed types equal? True
        Are the generic types equal? True
 */


.NET Framework

Compatible con: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Compatible con: 4, 3.5 SP1

Biblioteca de clases portable

Compatible con: Biblioteca de clases portable

.NET para aplicaciones de la Tienda Windows

Compatible con: Windows 8

.NET para aplicaciones de Windows Phone

Compatible con: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (no se admite el rol Server Core), Windows Server 2008 R2 (se admite el rol Server Core con SP1 o versiones posteriores; no se admite Itanium)

.NET Framework no admite todas las versiones de todas las plataformas. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft