Ответ 1
Скажите, что у вас есть следующий метод:
public static T Factory<T>() where T: new()
{
return new T();
}
Компилятор преобразует "return new T();" для вызова "CreateInstance".
Есть ли разница между двумя способами создания объекта.
Student s1 = Activator.CreateInstance<Student>();
Student s1 = new Student();
Скажите, что у вас есть следующий метод:
public static T Factory<T>() where T: new()
{
return new T();
}
Компилятор преобразует "return new T();" для вызова "CreateInstance".
Я бы не назвал Activator.CreateInstance()
избыточным.
Если вы знаете тип, да, вы просто используете new
. Однако в ситуациях, требующих динамической загрузки неизвестных типов из фреймворков плагинов или где тип анализируется из строки (например, с помощью файла настроек), он чрезвычайно полезен.
И чтобы ответить на вопрос о различии между ними, нет, под капотом нет никакой реальной разницы между вызовами new T()
и Activator.CreateInstance<T>()
, как уже было указано Andrew Hare.
РЕДАКТИРОВАТЬ: неважно, я путал общий CreateInstance<T>()
с более обычно используемым CreateInstance(Type type)
Вызов нового улучшен с точки зрения производительности. CreateInstance, вероятно, использует отражение, которое медленно.
Если вы знаете тип во время разработки - используйте новый, даже если оба вызова были точно такими же (это не так!), Почему чрезмерно усложнять свой код?
Используйте Activator.CreateInstance только тогда, когда вы не знаете тип T во время разработки, и вам нужно разрешение времени выполнения.
Нет, Activator.CreateInstance<T>
просто вызывает конструктор по умолчанию под обложками. Единственное различие между вашими примерами - вызов дополнительного метода CreateInstance<T>
.
Из Activator.CreateInstance<T>
:
Создает экземпляр типа обозначенный указанным общим типа, используя безразмерный конструктор.
Одно большое отличие состоит в том, что
Student s1 = new Student();
не будет компилироваться, если на Student
нет конструктора по умолчанию, тогда как
Student s1 = Activator.CreateInstance<Student>();
будет компилироваться, даже если Student
не имеет конструктора по умолчанию. (Он будет скомпилирован и позволит вам запустить программу, но если нет конструктора соответствия, вы получите исключение, тогда как вызов конструктора даже не будет компилироваться, если конструктор не существует.)
Аналогично, вызов CreateInstance
является неявным использованием класса, поэтому, например, Resharper не будет знать, что вы его создаете, и может сказать вам, что класс никогда не создается.
Как упоминалось в других ответах, вызов CreateInstance
также позволяет использовать параметр типового типа:
T s1 = Activator.CreateInstance<T>();
хотя вам, вероятно, будет лучше использовать ограничение типа new
, поскольку оно даст вам уверенность в компиляции, что на самом деле существует вызывающий конструктор.
Однако перегрузки Activator.CreateInstance(Type, ...)
гораздо полезнее.