2011-04-11 17 views
18

Con los genéricos que pueda¿Cómo crear una instancia para un tipo dado?

var object = default(T); 

Pero cuando todo lo que tienes es una instancia de tipo I sólo podía

constructor = type.GetConstructor(Type.EmptyTypes); 
var parameters = new object[0]; 
var obj = constructor.Invoke(parameters); 

o incluso

var obj = type.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); 

no existe un camino más corto, como la versión de genéricos?

Respuesta

19

El más cercano disponible es Activator.CreateInstance:

object o = Activator.CreateInstance(type); 

... pero por supuesto esto depende de la existencia de un constructor sin parámetros pública. (Otras sobrecargas le permiten especificar argumentos de constructor.)

He utilizado una variable explícitamente tipada aquí para dejar en claro que realmente no tenemos una variable del tipo en sí ... no puede escribir:

Type t = typeof(MemoryStream); 
// Won't compile 
MemoryStream ms = Activator.CreateInstance(t); 

por ejemplo. El tipo de tiempo de compilación del valor de retorno de CreateInstance siempre es object.

Tenga en cuenta que no lo hará default(T) crear una instancia de un tipo de referencia - le da el valor predeterminado para el tipo, que es una referencia nula para los tipos de referencia. Compare eso con CreateInstance que realmente crearía un nuevo objeto.

+0

¿Por qué no mencionar 'Activator.CreateInstanc ()'? – nawfal

+0

@nawfal: Porque el OP no conoce 'T', solo un 'Tipo' (como un valor de tiempo de ejecución). –

+0

Jon sí, la última línea de la pregunta me confundió. – nawfal

12

var myObject = Activator.CreateInstance(myType)

tienen que desechar si desea utilizar un parámetro escrito:

User user = (User)Activator.CreateInstance(typeof(User)); 

.. o con parámetros

User user = (User)Activator.CreateInstance(typeof(User), new object[]{firstName, lastName}); 

También puede utilizar los genéricos:

public T Create<T>() where T : class, new() 
{ 
    return new T(); 
} 

var user = Create<User>(); 
+1

+1 para el segundo enfoque. Me gusta mucho :) –

+0

Si el tipo es conocido en tiempo de compilación, entonces también podría usar Activator.CreateInstance (). –

+0

¿por qué restringir a las clases? *:) * – nawfal

0
Activator.CreateInstance(type) 
Cuestiones relacionadas