2009-08-17 9 views
25

He leído algunos bits y bobs en línea sobre este tema, pero no encontré ninguno que funcione para mí. Lo que intento hacer es crear una clase de Tipo de tiempo de ejecución.Activator.CreateInstance - Cómo crear instancias de clases que tienen constructores parametrizados

Uso Activator.CreateInstance que funciona bien para clases con constructores que no contienen argumentos. Para aquellos con argumentos arroja una excepción, ¿hay alguna forma de evitar esto?

Estoy más que feliz de pasar valores nulos o valores vacíos al ctor siempre que pueda crear la clase.

+0

(respondido a comentar) –

+0

cuestión no es un duplicado, pero las respuestas son: http://stackoverflow.com/questions/731452/create-instance-of-generic-type – nawfal

+0

posible duplicado de [ Cómo pasar los parámetros a Activator.CreateInstance ()] (http://stackoverflow.com/questions/2451336/how-to-pass-parameters-to-activator-createinstancet) –

Respuesta

7

finalmente terminé haciendo algo como esto - algunos de los comentaristas insinuó hacia esta solución de todos modos.

Repetí básicamente todos los constructores disponibles y elegí el más simple. Entonces creé datos nulos a pasar en el ctor (por lo que estoy usando para este enfoque está muy bien)

parte del código se ve un poco como esto

// If we have a ctor that requires parameters then pass null values 
if (requiresParameters) 
{ 
    List<object> parameters = new List<object>(); 
    ParameterInfo[] pInfos = constructorInfos[0].GetParameters(); 

    foreach (ParameterInfo pi in pInfos) 
    { 
     parameters.Add(createType(pi.ParameterType)); 
    } 

    return constructorInfos[0].Invoke(parameters.ToArray()); 
} 
+0

'constructorInfos [0] .GetParameters(). Seleccione (pi => createType (pi.ParameterType)). ToArray()' – ErikE

46

Hay una sobrecarga que acepta como argumentos params object[]:

object obj = Activator.CreateInstance(typeof(StringBuilder), "abc"); 

Sería esto hacer? Alternativa, se puede utilizar la reflexión para encontrar el constructor correcta:

Type[] argTypes = new Type[] {typeof(string)}; 
object[] argValues = new object[] {"abc"}; 
ConstructorInfo ctor = typeof(StringBuilder).GetConstructor(argTypes); 
object obj = ctor.Invoke(argValues); 
+0

Simplemente por curiosidad, ¿cuál sería mejor desde el punto de vista del rendimiento: obtener la lista de constructores e invocar un constructor particular a través de la reflexión o llamando directamente a Activator.CreateInstance con el objeto []? –

+1

Espero que el enfoque ConstructorInfo. De lo contrario, tiene que pensar en qué valores son compatibles con qué constructores, especialmente si ha pasado "nulo", etc. (que puede coincidir con múltiples constructores). –

+1

Pero podría cronometrarlo ;-p En realidad, si el rendimiento es una consideración importante, podría presentar un caso de una expresión LINQ precompilada (ya que esto es .NET 3.5) que representa el constructor. Avísame si quieres un ejemplo de esto. –

0

Activator.CreateInstance también tiene un montón de sobrecargas, uno es posible que desee comprobar hacia fuera es (tipo Tipo, objeto de argumento params []). Simplemente suministre los argumentos de constructor necesarios al segundo parámetro de esta llamada.

Asegúrese de controlar las excepciones aquí, sin embargo, ya que es fácil de pasar parámetros incorrectos o que algo cambie en los constructores del tipo más tarde que la rompe ..

1

estoy usando este método para obtener alrededor de an issue I ran into, y parece estar funcionando exactamente como esperaba. :)

object instance = Activator.CreateInstance(
    typeof(OpCode), 
    BindingFlags.NonPublic | BindingFlags.Instance, 
    default(Binder), 
    new object[] { stringname, pop, push, operand, type, size, s1, s2, ctrl, endsjmpblk, stack }, 
    default(CultureInfo)); 
+0

Puede usarse en cualquier tipo...? – Chris

0

Como alternativa a Activator.CreateInstance, FastObjectFactory en las preformas URL enlazado mejor que activador (como de .NET 4,0 y significativamente mejor que .NET 3.5. No hay pruebas/estadísticas hechas con .NET 4.5) . Vea la publicación de StackOverflow para estadísticas, información y código. Tenga en cuenta que es posible que sea necesario realizar algunas modificaciones en función del número de parametros de ctor. El código proporcionado solo permite 1 ctor param, pero puede modificarse para tener más de 1. Ver comentarios en el código.

How to pass ctor args in Activator.CreateInstance or use IL?

Cuestiones relacionadas