c# - tipos - Crear una instancia de un constructor con parámetros en una clase interna con reflejo
que es public class en programacion (4)
Tengo algo parecido a esto:
object[] parameter = new object[1];
parameter[0] = x;
object instantiatedType =
Activator.CreateInstance(typeToInstantiate, parameter);
y
internal class xxx : ICompare<Type>
{
private object[] x;
# region Constructors
internal xxx(object[] x)
{
this.x = x;
}
internal xxx()
{
}
...
}
Y entiendo:
lanzó excepción: System.MissingMethodException: Constructor en el tipo ''xxxx.xxx'' no encontrado ..
¿Algunas ideas?
(probado con éxito)
object instantiatedType =
Activator.CreateInstance(typeToInstantiate,
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance,
null, new object[] {parameter}, null);
Hay dos problemas que aborda esto:
- el
new object[] {parameter}
ayuda a manejar el problema de pasar unobject[]
como un único parámetro de método que toma un argumentoparams object[]
-
BindingFlags
ayuda a resolver el constructor no público
(los dos null
s se relacionan con la carpeta , el comportamiento predeterminado de la carpeta está bien para lo que queremos)
El problema es que Activator.CreateInstance(Type, object[])
no considera constructores no públicos.
Excepciones
MissingMethodException: no se encontró ningún constructor público coincidente.
Esto se muestra fácilmente al cambiar el constructor a visibilidad public
; el código luego funciona correctamente.
Aquí hay una solución (probada):
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
CultureInfo culture = null; // use InvariantCulture or other if you prefer
object instantiatedType =
Activator.CreateInstance(typeToInstantiate, flags, null, parameter, culture);
Si solo necesita el constructor sin parámetros, esto también funcionará:
//using the overload: public static object CreateInstance(Type type, bool nonPublic)
object instantiatedType = Activator.CreateInstance(typeToInstantiate, true)
Necesita llamar a una sobrecarga diferente de Activator.CreateInstance
que le permite pasar un parámetro no nonPublic
o BindingFlags
.
Encuentro todas estas sobrecargas CreateInstance
torpes; lo que prefiero hacer es:
-
typeToInstantiate.GetConstructor()
, pasandoBindingFlags.NonPublic
- Llamar a
ConstructorInfo.Invoke
, pasando el parámetro constructor
cambiarlo a
Activator.CreateInstance(typeToInstantiate,new object[] { parameter });
Esto se debe a que su constructor también espera que una matriz de objetos y un activador ya lo dividan en objetos separados