Uno no siempre sabe el Type
de un objeto en tiempo de compilación, pero es posible que deba crear una instancia de Type
.
¿Cómo se obtiene una nueva instancia de objeto de a Type
?
c#
.net
performance
reflection
types
etiquetas2k
fuente
fuente
ObjectType instance
coincide la condición del OP "Uno no siempre sabe el tipo de un objeto en tiempo de compilación"? : Pobject instance = Activator.CreateInstance(...);
.La
Activator
clase tiene una variante genérica que hace esto un poco más fácil:fuente
dynamic
construcción que hace permitir que tales construcciones, pero para la mayoría de los propósitos de esta respuesta todavía lo cubre.¡La expresión compilada es la mejor manera! (para que el rendimiento cree repetidamente una instancia en tiempo de ejecución).
Estadísticas (2012):
Estadísticas (2015, .net 4.5, x64):
Estadísticas (2015, .net 4.5, x86):
Estadísticas (2017, LINQPad 5.22.02 / x64 / .NET 4.6):
Estadísticas (2019, x64 / .NET 4.8):
Estadísticas (2019, x64 / .NET Core 3.0):
Código completo:
fuente
X
es en tiempo de ejecución?Type
.Una implementación de este problema es intentar llamar al constructor sin parámetros del Tipo:
Aquí está el mismo enfoque, contenido en un método genérico:
fuente
Es muy simple. Suponga que su nombre de clase es
Car
y el espacio de nombres esVehicles
, luego pase el parámetroVehicles.Car
que devuelve el objeto de tipoCar
. De esta manera, puede crear cualquier instancia de cualquier clase de forma dinámica.Si su nombre completo (es decir,
Vehicles.Car
en este caso) está en otro conjunto,Type.GetType
será nulo. En tales casos, debe recorrer todos los ensamblajes y buscar elType
. Para eso puedes usar el siguiente códigoY puede obtener la instancia llamando al método anterior.
fuente
Si se trata de algo que se llamará mucho en una instancia de aplicación, es mucho más rápido compilar y almacenar en caché el código dinámico en lugar de usar el activador o
ConstructorInfo.Invoke()
. Dos opciones fáciles para la compilación dinámica son las expresiones compiladas de Linq o algunosIL
códigos de operaciónDynamicMethod
simples y . De cualquier manera, la diferencia es enorme cuando comienzas a entrar en ciclos cerrados o llamadas múltiples.fuente
¿No funcionaría el genérico
T t = new T();
?fuente
Si desea utilizar el constructor predeterminado, entonces la solución que se
System.Activator
presenta anteriormente es probablemente la más conveniente. Sin embargo, si el tipo carece de un constructor predeterminado o si tiene que usar uno no predeterminado, entonces una opción es usar la reflexión oSystem.ComponentModel.TypeDescriptor
. En caso de reflexión, es suficiente saber solo el nombre del tipo (con su espacio de nombres).Ejemplo usando reflexión:
Ejemplo usando
TypeDescriptor
:fuente
args[]
fue exactamente lo que llegué a esta pregunta para encontrar, gracias!Sin uso de Reflection:
fuente
Ante este problema, el activador funcionará cuando haya un ctor sin parámetros. Si esto es una restricción, considere usar
fuente
fuente
Puedo superar esta pregunta porque estaba buscando implementar un método CloneObject simple para una clase arbitraria (con un constructor predeterminado)
Con el método genérico puede requerir que el tipo implemente New ().
Con no genérico, suponga que el tipo tiene un constructor predeterminado y captura una excepción si no lo tiene.
fuente