Разница Activator.CreateInstance(строка) и Activator.CreateInstance <T>()

Нет, это не вопрос дженериков.

У меня есть шаблон Factory с несколькими классами с внутренними конструкторами (я не хочу, чтобы они были созданы, если не через factory).

Моя проблема заключается в том, что CreateInstance не работает с ошибкой "Без параметров без конструктора, определенной для этого объекта", если я не передаю "истину" для непубличного параметра.

Пример

// Fails
Activator.CreateInstance(type);

// Works
Activator.CreateInstance(type, true);

Я хотел сделать общий Factory, чтобы сделать его немного проще, например:

public class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return Activator.CreateInstance<T>();
    }
}

Однако мне не удалось найти, как передать этот "истинный" параметр, чтобы он принимал непубличные конструкторы (внутренние).

Я что-то пропустил или это невозможно?

Ответ 1

Чтобы обойти это, не могли бы вы просто изменить свое использование как таковое:

public class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return Activator.CreateInstance(typeof(T), true);
    }
}

Ваш метод factory по-прежнему будет общим, но вызов активатору не будет использовать общую перегрузку. Но вы все равно должны достичь тех же результатов.

Ответ 2

Если вам абсолютно необходимо, чтобы конструктор был закрытым, вы можете попробовать что-то вроде этого:

public abstract class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return (T)Activator.CreateInstance(typeof(T), true);
    }
}

В противном случае вам лучше добавить новое ограничение и перейти по этому маршруту:

public abstract class GenericFactory<T> where T : MyAbstractType, new()
{
    public static T GetInstance()
    {
        return new T;
    }
}

Вы пытаетесь использовать GenericFactory в качестве базового класса для всех своих заводов, а не писать каждый с нуля?

Ответ 3

помимо Activator.CreateInstance(typeof (T), true) для работы, T должен иметь конструктор по умолчанию