Activator.CreateInstance - Как создать экземпляры классов, которые имеют параметризованные конструкторы
Я прочитал несколько бит и бобы в Интернете по этой теме, но не нашел ничего, что сработает для меня.
Я пытаюсь создать класс типа времени выполнения.
Я использую Activator.CreateInstance
, который отлично подходит для классов с конструкторами, которые не содержат аргументов. Для тех, у кого есть аргументы, они генерируют исключение, есть ли способ обойти это?
Я более чем счастлив передать null значения или пустые значения в ctor, пока я могу создать сам класс.
Ответы
Ответ 1
В конце концов я закончил делать что-то вроде этого - некоторые комментаторы намекали на это решение в любом случае.
Я в основном повторил все доступные конструкторы и выбрал самый простой. Затем я создал нулевые данные для передачи в ctor (для чего я использую его для этого подхода)
Часть кода выглядит примерно так:
// If we have a ctor that requires parameters then pass null values
if (requiresParameters)
{
List<object> parameters = new List<object>();
ParameterInfo[] pInfos = constructorInfos[0].GetParameters();
foreach (ParameterInfo pi in pInfos)
{
parameters.Add(createType(pi.ParameterType));
}
return constructorInfos[0].Invoke(parameters.ToArray());
}
Ответ 2
Существует перегрузка, которая принимает аргументы как params object[]
:
object obj = Activator.CreateInstance(typeof(StringBuilder), "abc");
Будет ли это делать? Альтернативно, вы можете использовать отражение, чтобы найти правильный конструктор:
Type[] argTypes = new Type[] {typeof(string)};
object[] argValues = new object[] {"abc"};
ConstructorInfo ctor = typeof(StringBuilder).GetConstructor(argTypes);
object obj = ctor.Invoke(argValues);
Ответ 3
Я использую этот метод, чтобы обойти проблему, с которой я столкнулся, и, похоже, работает так, как я надеялся.:)
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));
Ответ 4
Activator.CreateInstance также имеет целую кучу перегрузок, которую вы можете проверить (тип типа, params object [] args). Просто поставьте необходимые аргументы конструктора во второй параметр этого вызова.
Удостоверьтесь, что вы здесь обрабатываете исключения, так как легко передавать некорректные параметры в или для чего-то изменить в конструкторах типов позже, чем это нарушает его.
Ответ 5
В качестве альтернативы Activator.CreateInstance FastObjectFactory в связанном url преформы лучше, чем Activator (начиная с .NET 4.0 и значительно лучше, чем .NET 3.5. Нет тестов/статистических данных, выполненных с .NET 4.5). См. Сообщение StackOverflow для статистики, информации и кода. Обратите внимание, что некоторые модификации, возможно, потребуются в зависимости от количества ctor params. Предоставляемый код допускает только 1 ctor param, но может быть изменен, чтобы иметь более 1. См. Комментарии в коде.
Как передать ctor args в Activator.CreateInstance или использовать IL?