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?