Разница между Activator.CreateInstance(string) и Activator.CreateInstance<T>()

StackOverflow https://stackoverflow.com/questions/57439

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Пример

// Fails
Activator.CreateInstance(type);

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

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

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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 в качестве базового класса для всех ваших фабрик, а не писать каждую с нуля, верно?

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top