Можно не всегда знать Type
объект во время компиляции, но может потребоваться создать экземпляр объекта Type
.
Как вы получаете новый экземпляр объекта от Type
?
c#
.net
performance
reflection
types
tags2k
источник
источник
ObjectType instance
соответствует условию OP «Не всегда может быть известен тип объекта во время компиляции»? : Pobject instance = Activator.CreateInstance(...);
.У
Activator
класса есть универсальный вариант, который делает это немного проще:источник
dynamic
конструкцию , которая делает позволяют такие конструкции , но для большинства целей этот ответ еще охватывает ее.Скомпилированное выражение - лучший способ! (для производительности многократно создавать экземпляр во время выполнения).
Статистика (2012):
Статистика (2015, .net 4.5, x64):
Статистика (2015, .net 4.5, x86):
Статистика (2017, LINQPad 5.22.02 / x64 / .NET 4.6):
Статистика (2019, x64 / .NET 4.8):
Статистика (2019, x64 / .NET Core 3.0):
Полный код:
источник
X
во время выполнения?Type
.Одна из реализаций этой проблемы - попытаться вызвать конструктор типа без параметров:
Вот тот же подход, который содержится в универсальном методе:
источник
Это довольно просто. Предположим, что ваше имя класса
Car
и пространство имен естьVehicles
, затем передайте параметр,Vehicles.Car
который возвращает объект типаCar
. Таким образом, вы можете динамически создавать любой экземпляр любого класса.Если ваше полное имя (т.е.
Vehicles.Car
в данном случае) находится в другой сборке, оноType.GetType
будет нулевым. В таких случаях у вас есть цикл через все сборки и найтиType
. Для этого вы можете использовать следующий кодИ вы можете получить экземпляр, вызвав вышеуказанный метод.
источник
Если это что-то, что будет часто вызываться в экземпляре приложения, гораздо быстрее компилировать и кэшировать динамический код, чем использовать активатор или
ConstructorInfo.Invoke()
. Два простых варианта динамической компиляции - это скомпилированные выражения Linq или несколько простыхIL
кодов операций иDynamicMethod
. В любом случае, разница огромна, когда вы начинаете зацикливаться на нескольких вызовах.источник
Не будет ли общая
T t = new T();
работа?источник
Если вы хотите использовать конструктор по умолчанию, то решение с использованием
System.Activator
представленного ранее, вероятно, является наиболее удобным. Однако, если в типе отсутствует конструктор по умолчанию или вам нужно использовать конструктор не по умолчанию, тогда можно использовать отражение илиSystem.ComponentModel.TypeDescriptor
. В случае рефлексии достаточно знать только имя типа (с его пространством имен).Пример использования отражения:
Пример использования
TypeDescriptor
:источник
args[]
было именно то, что я пришел к этому вопросу, чтобы найти, спасибо!Без использования Reflection:
источник
Учитывая эту проблему, Активатор будет работать, когда есть ctor без параметров. Если это ограничение, рассмотрите возможность использования
источник
источник
Я могу ответить на этот вопрос, потому что я искал реализовать простой метод CloneObject для произвольного класса (с конструктором по умолчанию)
С универсальным методом вы можете потребовать, чтобы тип реализовал New ().
С неуниверсальным предположите, что у типа есть конструктор по умолчанию и поймайте исключение, если это не так.
источник