Activator.CreateInstance <T>по сравнению с новым - PullRequest
27 голосов
/ 30 октября 2009

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

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

Ответы [ 5 ]

11 голосов
/ 30 октября 2009

Эта перегрузка метода " Activator.CreateInstance " используется компиляторами для реализации создания типов, указанных параметрами типа, с использованием обобщений.

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

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

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

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

Подробнее: http://msdn.microsoft.com/en-us/library/0hcyx2kd.aspx

7 голосов
/ 30 октября 2009

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

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

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

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

4 голосов
/ 30 октября 2009

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

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

3 голосов
/ 01 апреля 2014

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

Student s1 = new Student();

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

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

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

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

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

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

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

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

3 голосов
/ 30 октября 2009

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

С Activator.CreateInstance<T>:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...