Создание экземпляра конструктора с параметрами во внутреннем классе с отражением
У меня есть что-то вроде этого:
object[] parameter = new object[1];
parameter[0] = x;
object instantiatedType =
Activator.CreateInstance(typeToInstantiate, parameter);
и
internal class xxx : ICompare<Type>
{
private object[] x;
# region Constructors
internal xxx(object[] x)
{
this.x = x;
}
internal xxx()
{
}
...
}
И я получаю:
заброшено исключение: System.MissingMethodException: конструктор по типу "xxxx.xxx" не найден..
Любые идеи?
Ответы
Ответ 1
Проблема заключается в том, что Activator.CreateInstance(Type, object[])
не рассматривает непубличные конструкторы.
Исключения
MissingMethodException: нет совпадений открытый конструктор.
Это легко показать, изменив конструктор на public
видимость; код затем работает правильно.
Здесь один обход (проверенный):
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);
Если вам нужен только конструктор без параметров, это также будет работать:
//using the overload: public static object CreateInstance(Type type, bool nonPublic)
object instantiatedType = Activator.CreateInstance(typeToInstantiate, true)
Ответ 2
(успешно протестирован)
object instantiatedType =
Activator.CreateInstance(typeToInstantiate,
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance,
null, new object[] {parameter}, null);
Есть два вопроса:
-
new object[] {parameter}
помогает справиться с проблемой передачи object[]
как одиночного параметра метода, который принимает аргумент params object[]
-
BindingFlags
помогает разрешить непубличный конструктор
(два null
относятся к связующему, поведение связующего по умолчанию отлично подходит для того, что мы хотим)
Ответ 3
Вам нужно вызвать другую перегрузку Activator.CreateInstance
, которая позволяет передать параметр nonPublic
или BindingFlags
.
Я нахожу все эти перегрузки CreateInstance
неуклюжими; я предпочитаю делать это:
- Вызов
typeToInstantiate.GetConstructor()
, передача BindingFlags.NonPublic
- Вызвать
ConstructorInfo.Invoke
, передав ему параметр конструктора
Ответ 4
измените его на
Activator.CreateInstance(typeToInstantiate,new object[] { parameter });
Это связано с тем, что ваш конструктор также ожидает, что массив объектов и активатор уже разбивают его на отдельные объекты