2010-10-08 13 views
7

Supongamos que tengo una clase desconocida hasta el tiempo de ejecución. En tiempo de ejecución obtengo una referencia, x, del tipo Tipo que hace referencia a Foo.GetType(). Solo al usar x y la Lista <>, ¿puedo crear una lista de tipo Foo?¿Cómo crear una instancia de la lista <T> pero T es desconocido hasta el tiempo de ejecución?

¿Cómo hacer eso?

+3

¿Algo que te detenga simplemente creando una 'Lista '? – Flynn1179

+0

@ Flynn1179, déjame ver cómo lo haces por favor. – xport

+0

'List myList = new List ();' – Flynn1179

Respuesta

19
Type x = typeof(Foo); 
Type listType = typeof(List<>).MakeGenericType(x); 
object list = Activator.CreateInstance(listType); 

Por supuesto, usted no debe esperar ningún tipo de seguridad aquí como la lista resultante es de tipo object en tiempo de compilación. El uso de List<object> sería más práctico, pero aún de tipo de seguridad limitada, ya que el tipo de Foo se conoce solo en tiempo de ejecución.

+0

¡Agradable! Su respuesta también sugiere (correctamente) que trabajar con una lista así será bastante inseguro. Uno podría, por supuesto, declarar 'list' como de tipo (no genérico)' IList' o 'ICollection' (en lugar de simplemente' object'), acompañado por un molde correspondiente del retorno 'Activator.CreateInstance' valor, de modo que una forma limitada de trabajar con 'list' como una colección sea posible. – stakx

+2

Si crea tipos en tiempo de ejecución, seguro que no puede haber ningún tipo de seguridad de tipo de tiempo de compilación. – Frank

0

Algo como esto:

Activator.CreateInstance (typeof (Lista <>) MakeGenericType (tipo).)

11

Claro que puedes:

var fooList = Activator 
    .CreateInstance(typeof(List<>) 
    .MakeGenericType(Foo.GetType())); 

El problema aquí es que es fooList del tipo object por lo que aún tendría que convertirlo en un tipo "utilizable". Pero, ¿cómo se vería este tipo? Como una estructura de datos que admite agregar y buscar objetos del tipo TList<T> (o más bien IList<>) no es covariante en T por lo que no puede convertir List<Foo> en List<IFoo> donde Foo: IFoo. Puede convertirlo a IEnumerable<T>, que es covariante en T.

Si está utilizando C# 4.0, también podría considerar el envío de fooList al para que al menos pueda usarlo como una lista (por ejemplo, agregar, buscar y eliminar objetos).

Teniendo en cuenta todo esto y el hecho de que no tiene ningún tipo de seguridad en tiempo de compilación al crear tipos en tiempo de ejecución de todos modos, simplemente usar List<object> es probablemente la mejor/más pragmática manera de ir en este caso.

Cuestiones relacionadas