2010-03-18 25 views

Respuesta

25

Es posible, pero no necesariamente útil, ya que no se podía utilizar realmente desde el código compilado tan inflexible. El código de creación sería

Type myType; 
    Type listType = typeof(List<>).MakeGenericType(myType); 
    IList myList = (IList)Activator.CreateInstance(listType); 
+0

Works. Cheers! :) – AndrewC

+3

Tenga en cuenta que existe una diferencia entre "fuertemente tipado" y "estáticamente tipado". Se pierde la comprobación de tipo estático aquí, pero myList le impedirá agregar objetos que no sean instancias myType válidas. – Lee

+0

@Lee, gracias por la aclaración. –

9

Sí. Puede hacerlo a través de Reflection, usando Type.MakeGenericType y Activator.CreateInstance.

IList MakeListOfType(Type listType) 
{ 
    Type listType = typeof(List<>); 
    Type specificListType = listType.MakeGenericType(listType); 

    return (IList)Activator.CreateInstance(specificListType); 
} 
+0

por qué el downvotes? –

+2

tiene un listType de parámetro y un listType de campo local, imagino que algunas personas estarían confundidas por eso (no devolví) – Martin

-1

sí usando genérica que puede hacer algo como esto

var asd = METHOD<Button>(); 

    List<t> METHOD<t>() 
    { 
     return new List<t>(); 
    } 
+0

¿por qué? = (........ – Luiscencio

+0

el tipo "Botón" está codificado, no es el tiempo de ejecución – Martin

+0

OP solicitó que se determine la t en tiempo de ejecución. En su ejemplo, está configurado en tiempo de compilación. –

1

Sí. Sin embargo, no podrá asignarlo a una variable que tenga un tipo genérico ya que la T en este caso no se decidirá hasta el tiempo de ejecución. (Si usted está pensando que la función de covarianza .NET 4.0 le ayudará y dejar que se declara la variable como IList<SomeSuperType>, no será como el T es utilizado por List<T> tanto para in y out propósitos.)

Nota del inusual Listar <> sintaxis para acceder al tipo genérico "no estructurado".

public static System.Collections.IList ConstructGenericList(Type t) 
    { 
     return (System.Collections.IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t)); 
    } 
+1

(re varianza, que también solo funciona para interfaces/delegados; no clases) –

+0

@Marc, a la derecha ... Debería haber escrito 'IList '. Fijación. –

1

Para DataContractSerializer tipos conocidos es posible que desee para abastecer no sólo a los tipos de montaje, sino también su lista de que los tipos:

public static List<Type> GetKnownTypesForDataContractSerializer() 
{ 
    Assembly a = Assembly.GetExecutingAssembly(); 
    Type[] array = a.GetExportedTypes(); 

    List<Type> lista = array.ToList(); 

    lista = lista.FindAll(item => ((item.IsClass || item.IsEnum) & !item.IsGenericType & !item.IsAbstract == true)); 



    List<Type> withEnumerable = new List<Type>(); 
    foreach (Type t in lista) 
    { 
     withEnumerable.Add(t); //add basic type 

     //now create List<> type 
     Type listType = typeof(List<>); 
     var listOfType = listType.MakeGenericType(t); 

     withEnumerable.Add(listOfType); //add Type of List<basic type> 
    } 

    return withEnumerable; 
} 
Cuestiones relacionadas