2009-08-18 8 views
13

Perdóname si esta pregunta ya se ha hecho y respondido.Diferencia entre Activator.CreateInstance() y typeof (T) .InvokeMember() con BindingFlags.CreateInstance

Dada una clase de tipo T, ¿cuál es la diferencia entre los siguientes?

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

T myObj = typeof(T).InvokeMember(null, BindingFlags.CreateInstance, null, null, null); 

¿Se prefiere una solución sobre la otra?

+2

FWIW: 'Activator.CreateInstance ()' es más correcto para su primer ejemplo, ya que no requerirá un lanzamiento del resultado a 'T'. –

+0

@Steve Guidi: Gracias. Actualizaré la pregunta. –

Respuesta

11

Descompilación RuntimeType.InvokeMember produce este fragmento:

if ((bindingFlags & BindingFlags.CreateInstance) != BindingFlags.Default) 
{ 
    if (((bindingFlags & BindingFlags.CreateInstance) != BindingFlags.Default) && ((bindingFlags & (BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.SetField | BindingFlags.GetField | BindingFlags.InvokeMethod)) != BindingFlags.Default)) 
    { 
     throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"), "bindingFlags"); 
    } 
    return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture); 
} 

En otras palabras, InvokeMember con los BindingFlags llama Activator.CreateInstance. Pasa por varias capas de llamada más (verificando enlaces, verificando argumentos) antes de ponerse a trabajar. Activator.CreateInstance<T> es mucho más sucinta:

public static T CreateInstance<T>() 
{ 
    bool bNeedSecurityCheck = true; 
    bool canBeCached = false; 
    RuntimeMethodHandle emptyHandle = RuntimeMethodHandle.EmptyHandle; 
    return (T) RuntimeTypeHandle.CreateInstance(typeof(T) as RuntimeType, true, true, ref canBeCached, ref emptyHandle, ref bNeedSecurityCheck); 
} 

editado Se podría esperar que ésta sea más rápido, pero un método llamado RuntimeType.CreateInstanceSlow también llamadas RuntimeTypeHandle.CreateInstance para hacer el trabajo; se usa como alternativa si no se puede encontrar una entrada de caché Activador para el constructor. Haría algunas pruebas de rendimiento si estás buscando la solución más rápida de las dos.

Cuestiones relacionadas