2009-08-18 16 views
13

Perdonami se questa domanda è già stata fatta e ha risposto.Differenza tra Activator.CreateInstance() e typeof (T) .InvokeMember() con BindingFlags.CreateInstance

Data una classe di tipo T, qual è la differenza tra quanto segue?

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

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

È una soluzione preferita rispetto all'altra?

+2

FWIW: 'Activator.CreateInstance ()' è più corretto per il tuo primo esempio, in quanto non richiede un cast del risultato a 'T'. –

+0

@Steve Guidi: Grazie. Aggiornerò la domanda –

risposta

11

Decompiling RuntimeType.InvokeMember cede questo frammento:

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); 
} 

In altre parole, InvokeMember con quelli BindingFlags chiama Activator.CreateInstance. Passa attraverso molti altri livelli di chiamata (controllando i collegamenti, verificando gli argomenti) prima di mettersi al lavoro. Activator.CreateInstance<T> è molto più succinta:

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); 
} 

a cura Ci si potrebbe aspettare a quest'ultimo di essere più veloce, ma un metodo chiamato RuntimeType.CreateInstanceSlow chiamate anche RuntimeTypeHandle.CreateInstance per fare il lavoro; è usato come fallback se non è possibile trovare una voce della cache di Activator per il costruttore. Farei dei test delle prestazioni se stai cercando la soluzione più veloce tra i due.

Problemi correlati