2009-08-18 17 views
13

Przebacz mi, jeśli to pytanie zostało już zadane i udzielono odpowiedzi.Różnica między Activator.CreateInstance() i typeof (T) .InvokeMember() z BindingFlags.CreateInstance

Biorąc pod uwagę klasę typu T, jaka jest różnica między poniższymi?

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

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

Czy jedno rozwiązanie jest preferowane w stosunku do innych?

+2

FWIW: 'Activator.CreateInstance ()' jest bardziej poprawne dla twojego pierwszego przykładu, ponieważ nie będzie wymagało rzutowania wyniku na 'T'. –

+0

@Steve Guidi: Dzięki. Zaktualizuję pytanie. –

Odpowiedz

11

Dekodowanie RuntimeType.InvokeMember daje ten fragment:

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

Innymi słowy, InvokeMember z tymi BindingFlags wzywa Activator.CreateInstance. Przechodzi przez kilka kolejnych warstw wywołań (sprawdzanie powiązań, sprawdzanie argumentów) przed przejściem do biznesu. Activator.CreateInstance<T> jest bardziej zwięzły:

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

EDITED Można oczekiwać, że ten ostatni będzie szybciej, ale to metoda zwana RuntimeType.CreateInstanceSlowRuntimeTypeHandle.CreateInstance wzywa również do pracy; jest używany jako rezerwowy, jeśli nie można znaleźć pozycji pamięci podręcznej programu Activator dla konstruktora. Zrobiłbym test wydajności, jeśli szukasz najszybszego rozwiązania z tych dwóch.

Powiązane problemy