代码之家  ›  专栏  ›  技术社区  ›  Matt Davis

Activator.CreateInstance()和带有BindingFlags.CreateInstance的typeof(T.InvokeMember()之间的差异

  •  14
  • Matt Davis  · 技术社区  · 15 年前

    如果这个问题已经被问到和回答了,请原谅我。

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

    一种解决方案是否优于另一种?

    1 回复  |  直到 12 年前
        1
  •  13
  •   Ben M    15 年前

    反编译 RuntimeType.InvokeMember 产生这个片段:

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

    InvokeMember 用那些 BindingFlags 电话 Activator.CreateInstance . 在开始工作之前,它还要经过几个调用层(检查绑定、验证参数)。 Activator.CreateInstance<T>

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

    您可能期望后者速度更快,但是 RuntimeType.CreateInstanceSlow 也叫 RuntimeTypeHandle.CreateInstance