Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Activator.CreateInstance() and typeof(T).InvokeMember() with BindingFlags.CreateInstance

Tags:

c#

.net

Forgive me if this question has already been asked and answered.

Given a class of type T, what is the difference between the following?

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

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

Is one solution preferred over the other?

like image 630
Matt Davis Avatar asked Aug 18 '09 17:08

Matt Davis


People also ask

What is activator CreateInstance?

The Activator. CreateInstance method creates an instance of a type defined in an assembly by invoking the constructor that best matches the specified arguments. If no arguments are specified then the constructor that takes no parameters, that is, the default constructor, is invoked.

What is activator CreateInstance in net core?

CreateInstance(ActivationContext, String[]) Creates an instance of the type that is designated by the specified ActivationContext object and activated with the specified custom activation data. CreateInstance(Type) Creates an instance of the specified type using that type's parameterless constructor.

What is activator class in C#?

Activator Class in . NET 4.0. Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects. ActivatorClassSample.rar. Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects.


1 Answers

Decompiling RuntimeType.InvokeMember yields this 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);
}

In other words, InvokeMember with those BindingFlags calls Activator.CreateInstance. It goes through several more call layers (checking bindings, verifying arguments) before getting down to business. Activator.CreateInstance<T> is much more succinct:

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 You might expect the latter to be faster, but a method called RuntimeType.CreateInstanceSlow also calls RuntimeTypeHandle.CreateInstance to do the work; it's used as a fallback if an Activator cache entry for the constructor can't be found. I'd do some performance testing if you're looking for the fastest solution of the two.

like image 63
Ben M Avatar answered Oct 05 '22 05:10

Ben M