Activator.CreateInstance – Cómo crear instancias de clases que tienen constructores parametrizados

He leído algunos fragmentos en línea sobre este tema, pero no he encontrado ninguno que funcione para mí. Lo que estoy tratando de hacer es crear una clase de un Tipo de tiempo de ejecución.

Uso Activator.CreateInstance que funciona bien para las clases con constructores que no contienen argumentos. Para aquellos con argumentos, lanza 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 en sí.

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

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

¿Esto haría? Alternativamente, puedes usar la reflexión para encontrar el constructor correcto:

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

Finalmente, terminé haciendo algo como esto: algunos de los comentaristas insinuaron esta solución de todos modos.

Básicamente iteré a través de todos los constructores disponibles y elegí el más simple. Luego creé datos nulos para pasar al ctor (por lo que estoy usando para este enfoque está bien)

Parte del código se ve un poco así.

 // If we have a ctor that requires parameters then pass null values if (requiresParameters) { List parameters = new List(); ParameterInfo[] pInfos = constructorInfos[0].GetParameters(); foreach (ParameterInfo pi in pInfos) { parameters.Add(createType(pi.ParameterType)); } return constructorInfos[0].Invoke(parameters.ToArray()); } 

Estoy usando este método para solucionar un problema que encontré , 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)); 

Activator.CreateInstance también tiene una gran cantidad de sobrecargas, una de las que querría revisar es (Type type, params object [] args). Simplemente suministre los argumentos de constructor requeridos al segundo parámetro de esta llamada.

Sin embargo, asegúrese de manejar las excepciones aquí, ya que es fácil pasar parámetros incorrectos o que algo cambie en los constructores del tipo más adelante que lo rompan.

Como alternativa a Activator.CreateInstance, FastObjectFactory en las preformas de URL vinculadas es mejor que Activator (a partir de .NET 4.0 y significativamente mejor que .NET 3.5. No se realizan pruebas / estadísticas con .NET 4.5). Ver la publicación 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 parámetros Ctor. El código provisto solo permite 1 parámetro de ctor pero se puede modificar para que tenga más de 1. Ver comentarios en el código

¿Cómo pasar ctor args en Activator.CreateInstance o usar IL?