Подтвердить что ты не робот

Activator.CreateInstance <T> Vs new

Есть ли разница между двумя способами создания объекта.

Student s1 = Activator.CreateInstance<Student>();
Student s1 = new Student();
  • Есть ли разница в том, как вызывается конструктор или инициализирует память?
  • В моем понимании первый метод выглядит полностью избыточным. Если программист знает тип данных во время разработки, он будет использовать второй метод.
4b9b3361

Ответ 1

Эта перегрузка метода

Скажите, что у вас есть следующий метод:

public static T Factory<T>() where T: new()
{
    return new T();
}

Компилятор преобразует "return new T();" для вызова "CreateInstance".

В общем случае для кода CreateInstance в приложении не используется, поскольку тип должен быть известен во время компиляции. Если тип известен во время компиляции, может использоваться стандартный синтаксис создания экземпляра (новый оператор в С#, New в Visual Basic, gcnew в С++).

Дополнительная информация:

Ответ 2

Я бы не назвал Activator.CreateInstance() избыточным.

Если вы знаете тип, да, вы просто используете new. Однако в ситуациях, требующих динамической загрузки неизвестных типов из фреймворков плагинов или где тип анализируется из строки (например, с помощью файла настроек), он чрезвычайно полезен.

И чтобы ответить на вопрос о различии между ними, нет, под капотом нет никакой реальной разницы между вызовами new T() и Activator.CreateInstance<T>(), как уже было указано Andrew Hare.

РЕДАКТИРОВАТЬ: неважно, я путал общий CreateInstance<T>() с более обычно используемым CreateInstance(Type type)

Ответ 3

Вызов нового улучшен с точки зрения производительности. CreateInstance, вероятно, использует отражение, которое медленно.
Если вы знаете тип во время разработки - используйте новый, даже если оба вызова были точно такими же (это не так!), Почему чрезмерно усложнять свой код?

Используйте Activator.CreateInstance только тогда, когда вы не знаете тип T во время разработки, и вам нужно разрешение времени выполнения.

Ответ 4

Нет, Activator.CreateInstance<T> просто вызывает конструктор по умолчанию под обложками. Единственное различие между вашими примерами - вызов дополнительного метода CreateInstance<T>.

Из Activator.CreateInstance<T>:

Создает экземпляр типа обозначенный указанным общим типа, используя безразмерный конструктор.

Ответ 5

Одно большое отличие состоит в том, что

Student s1 = new Student();

не будет компилироваться, если на Student нет конструктора по умолчанию, тогда как

Student s1 = Activator.CreateInstance<Student>();

будет компилироваться, даже если Student не имеет конструктора по умолчанию. (Он будет скомпилирован и позволит вам запустить программу, но если нет конструктора соответствия, вы получите исключение, тогда как вызов конструктора даже не будет компилироваться, если конструктор не существует.)

Аналогично, вызов CreateInstance является неявным использованием класса, поэтому, например, Resharper не будет знать, что вы его создаете, и может сказать вам, что класс никогда не создается.

Как упоминалось в других ответах, вызов CreateInstance также позволяет использовать параметр типового типа:

T s1 = Activator.CreateInstance<T>();

хотя вам, вероятно, будет лучше использовать ограничение типа new, поскольку оно даст вам уверенность в компиляции, что на самом деле существует вызывающий конструктор.

Однако перегрузки Activator.CreateInstance(Type, ...) гораздо полезнее.