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

前端 未结 1 718
遥遥无期
遥遥无期 2020-12-18 21:00

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 = Act         


        
相关标签:
1条回答
  • 2020-12-18 21:31

    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.

    0 讨论(0)
提交回复
热议问题