2012-02-29 15 views
7

Dado el siguiente código de ejemplo;Activator.CreateInstance (...) no encuentra el constructor con parámetros

class Program 
{ 
    static void Main(string[] args) 
    { 
     var results = GetChildren().ToList(); 
    } 

    static IEnumerable<MyBaseClass> GetChildren() 
    { 
     return Assembly.GetExecutingAssembly() 
      .GetTypes() 
      .Where(t => t.BaseType == typeof(MyBaseClass)) 
      .Select(o => (MyBaseClass)Activator.CreateInstance(o, null)); 
    } 
} 

abstract class MyBaseClass 
{ } 

class MyChildClass : MyBaseClass 
{ 
    public MyChildClass(object paramOne) 
    { 

    } 
} 

Recibo el siguiente error;

MissingMethodException: Constructor del tipo 'CreateInstanceCtorIssue.MyChildClass' not found.

Sin embargo, si agrego un constructor sin parámetros, crea los objetos OK.

Estoy tratando de averiguar por qué el parámetro que estoy suministrando a CreateInstance no hace que encuentre el constructor correcto. ¿Alguien tiene alguna idea?

+1

Esto debería funcionar: 'Activator.CreateInstance (O, (objeto) null)' – Alex

Respuesta

10

Básicamente, el segundo argumento del method you are calling es un params array. Lo que sucede es que el compilador de C# está tratando su método-llamada como si estuviera pasando este argumento al usar el formulario "no expandido", es decir, al pasar una null matriz-referencia. Por otro lado, su intención es usar la forma "expandida", es decir, pasar una referencia a una matriz que contiene una única referencia nula.

Puede convencer al compilador para hacer lo que quiere de esta manera:

// Unexpanded: 
Activator.CreateInstance(o, new object[] { null }) 

// Expanded explictly: 
Activator.CreateInstance(o, (object) null) 
+0

Ese fue de hecho el problema, muchas gracias. Acabo de asumir que el compilador interpretaría el nulo que estaba pasando como parte de la matriz params, que obviamente es incorrecta cuando lo piensas. ¡Aclamaciones! –

+0

¡Esto salvó mi @@ s !! ¡No puedo votar lo suficiente! – Cornelius

3

usted tiene que pasar los parámetros del constructor:

.Select(o => (MyBaseClass)Activator.CreateInstance(o, new object[] { someParam })); 

MyChildClass espera un único parámetro de tipo de objeto de su constructor - usted tiene que pasar este parámetro dentro de una matriz.

+2

favor responda * * ¿Por qué tiene que pasar dentro de una matriz. La naturaleza 'params' del segundo parámetro de' CreateInstance' sugiere que uno debe * no * tener que pasar en una matriz. – ErikE

+0

de acuerdo. necesita alguna explicación normalmente no tendrías que calificar un a params explícitamente como un [] sino simplemente pasar en param1, param2. Después de todo, ¿por qué existen los params? ¿Por qué es necesario aquí? –

Cuestiones relacionadas