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[] -
BindingFlagsayuda 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