开发者

Activator.CreateInstance Performance Alternative

I'm using RedGate to do some performance evaluation. I notice dynamically creating an instance using Activator.CreateInstance (with tw开发者_高级运维o constructor parameters) is taking a decent amount of time... is there a better alternative that still utilizes a reflective approach (not explicit instantiation)?


Use a compiled lambda if you can, its MUCH faster.

https://vagifabilov.wordpress.com/2010/04/02/dont-use-activator-createinstance-or-constructorinfo-invoke-use-compiled-lambda-expressions/


Don't forget about DynamicMethod

Here's example how to create new instance thru default constructor

public static ObjectActivator CreateCtor(Type type)
{
    if (type == null)
    {
        throw new NullReferenceException("type");
    }
    ConstructorInfo emptyConstructor = type.GetConstructor(Type.EmptyTypes);
    var dynamicMethod = new DynamicMethod("CreateInstance", type, Type.EmptyTypes, true);
    ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
    ilGenerator.Emit(OpCodes.Nop);
    ilGenerator.Emit(OpCodes.Newobj, emptyConstructor);
    ilGenerator.Emit(OpCodes.Ret);
    return (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator));
}

public delegate object ObjectActivator();

here's more about performance comparison

Measuring InvokeMember... 1000000 iterations in 1.5643784 seconds.

Measuring MethodInfo.Invoke... 1000000 iterations in 0.8150111 seconds.

Measuring DynamicMethod... 1000000 iterations in 0.0330202 seconds.

Measuring direct call... 1000000 iterations in 0.0136752 seconds.


I have created a solution that can be used as a drop in replacement for Activator.CreateInstance. You can find it on my blog.

Example:

var myInstance = InstanceFactory.CreateInstance(typeof(MyClass));
var myArray1 = InstanceFactory.CreateInstance(typeof(int[]), 1024);
var myArray2 = InstanceFactory.CreateInstance(typeof(int[]), new object[] { 1024 });

Code:

public static class InstanceFactory
{
  private delegate object CreateDelegate(Type type, object arg1, object arg2, object arg3);

  private static ConcurrentDictionary<Tuple<Type, Type, Type, Type>, CreateDelegate> cachedFuncs = new ConcurrentDictionary<Tuple<Type, Type, Type, Type>, CreateDelegate>();

  public static object CreateInstance(Type type)
  {
    return InstanceFactoryGeneric<TypeToIgnore, TypeToIgnore, TypeToIgnore>.CreateInstance(type, null, null, null);
  }

  public static object CreateInstance<TArg1>(Type type, TArg1 arg1)
  {
    return InstanceFactoryGeneric<TArg1, TypeToIgnore, TypeToIgnore>.CreateInstance(type, arg1, null, null);
  }

  public static object CreateInstance<TArg1, TArg2>(Type type, TArg1 arg1, TArg2 arg2)
  {
    return InstanceFactoryGeneric<TArg1, TArg2, TypeToIgnore>.CreateInstance(type, arg1, arg2, null);
  }

  public static object CreateInstance<TArg1, TArg2, TArg3>(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
  {
    return InstanceFactoryGeneric<TArg1, TArg2, TArg3>.CreateInstance(type, arg1, arg2, arg3);
  }

  public static object CreateInstance(Type type, params object[] args)
  {
    if (args == null)
      return CreateInstance(type);

    if (args.Length > 3 || 
      (args.Length > 0 && args[0] == null) ||
      (args.Length > 1 && args[1] == null) ||
      (args.Length > 2 && args[2] == null))
    {
        return Activator.CreateInstance(type, args);   
    }

    var arg0 = args.Length > 0 ? args[0] : null;
    var arg1 = args.Length > 1 ? args[1] : null;
    var arg2 = args.Length > 2 ? args[2] : null;

    var key = Tuple.Create(
      type,
      arg0?.GetType() ?? typeof(TypeToIgnore),
      arg1?.GetType() ?? typeof(TypeToIgnore),
      arg2?.GetType() ?? typeof(TypeToIgnore));

    if (cachedFuncs.TryGetValue(key, out CreateDelegate func))
      return func(type, arg0, arg1, arg2);
    else
      return CacheFunc(key)(type, arg0, arg1, arg2);
  }

  private static CreateDelegate CacheFunc(Tuple<Type, Type, Type, Type> key)
  {
    var types = new Type[] { key.Item1, key.Item2, key.Item3, key.Item4 };
    var method = typeof(InstanceFactory).GetMethods()
                                        .Where(m => m.Name == "CreateInstance")
                                        .Where(m => m.GetParameters().Count() == 4).Single();
    var generic = method.MakeGenericMethod(new Type[] { key.Item2, key.Item3, key.Item4 });

    var paramExpr = new List<ParameterExpression>();
    paramExpr.Add(Expression.Parameter(typeof(Type)));
    for (int i = 0; i < 3; i++)
      paramExpr.Add(Expression.Parameter(typeof(object)));

    var callParamExpr = new List<Expression>();
    callParamExpr.Add(paramExpr[0]);
    for (int i = 1; i < 4; i++)
      callParamExpr.Add(Expression.Convert(paramExpr[i], types[i]));

    var callExpr = Expression.Call(generic, callParamExpr);
    var lambdaExpr = Expression.Lambda<CreateDelegate>(callExpr, paramExpr);
    var func = lambdaExpr.Compile();
    cachedFuncs.TryAdd(key, func);
    return func;
  }
}

public static class InstanceFactoryGeneric<TArg1, TArg2, TArg3>
{
  private static ConcurrentDictionary<Type, Func<TArg1, TArg2, TArg3, object>> cachedFuncs = new ConcurrentDictionary<Type, Func<TArg1, TArg2, TArg3, object>>();

  public static object CreateInstance(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
  {
    if (cachedFuncs.TryGetValue(type, out Func<TArg1, TArg2, TArg3, object> func))
      return func(arg1, arg2, arg3);
    else
      return CacheFunc(type, arg1, arg2, arg3)(arg1, arg2, arg3);
  }

  private static Func<TArg1, TArg2, TArg3, object> CacheFunc(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
  {
    var constructorTypes = new List<Type>();
    if (typeof(TArg1) != typeof(TypeToIgnore))
      constructorTypes.Add(typeof(TArg1));
    if (typeof(TArg2) != typeof(TypeToIgnore))
      constructorTypes.Add(typeof(TArg2));
    if (typeof(TArg3) != typeof(TypeToIgnore))
      constructorTypes.Add(typeof(TArg3));

    var parameters = new List<ParameterExpression>()
    {
      Expression.Parameter(typeof(TArg1)),
      Expression.Parameter(typeof(TArg2)),
      Expression.Parameter(typeof(TArg3)),
    };

    var constructor = type.GetConstructor(constructorTypes.ToArray());
    var constructorParameters = parameters.Take(constructorTypes.Count).ToList();
    var newExpr = Expression.New(constructor, constructorParameters);
    var lambdaExpr = Expression.Lambda<Func<TArg1, TArg2, TArg3, object>>(newExpr, parameters);
    var func = lambdaExpr.Compile();
    cachedFuncs.TryAdd(type, func);
    return func;
  }
}

public class TypeToIgnore
{
}


If you're looking for a set of predefined methods that cover 1-16 parameters, here you go:

using System;
using System.Linq.Expressions;
using System.Reflection;

namespace YournamespaceHere;

public class Constructors<TKnownType>
{
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15), typeof(T16) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var t12 = Expression.Parameter(typeof(T12), "t12");
        var t13 = Expression.Parameter(typeof(T13), "t13");
        var t14 = Expression.Parameter(typeof(T14), "t14");
        var t15 = Expression.Parameter(typeof(T15), "t15");
        var t16 = Expression.Parameter(typeof(T16), "t16");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var t12 = Expression.Parameter(typeof(T12), "t12");
        var t13 = Expression.Parameter(typeof(T13), "t13");
        var t14 = Expression.Parameter(typeof(T14), "t14");
        var t15 = Expression.Parameter(typeof(T15), "t15");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var t12 = Expression.Parameter(typeof(T12), "t12");
        var t13 = Expression.Parameter(typeof(T13), "t13");
        var t14 = Expression.Parameter(typeof(T14), "t14");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var t12 = Expression.Parameter(typeof(T12), "t12");
        var t13 = Expression.Parameter(typeof(T13), "t13");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var t12 = Expression.Parameter(typeof(T12), "t12");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var t11 = Expression.Parameter(typeof(T11), "t11");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var t10 = Expression.Parameter(typeof(T10), "t10");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var t9 = Expression.Parameter(typeof(T9), "t9");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8, t9);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8, t9).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, TKnownType> New<T1, T2, T3, T4, T5, T6, T7, T8>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var t8 = Expression.Parameter(typeof(T8), "t8");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7, t8);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7, t8).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, T7, TKnownType> New<T1, T2, T3, T4, T5, T6, T7>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var t7 = Expression.Parameter(typeof(T7), "t7");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6, t7);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6, t7).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, T6, TKnownType> New<T1, T2, T3, T4, T5, T6>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var t6 = Expression.Parameter(typeof(T6), "t6");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5, t6);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, TKnownType>>(newExpression, t1, t2, t3, t4, t5, t6).Compile();
    }
    public static Func<T1, T2, T3, T4, T5, TKnownType> New<T1, T2, T3, T4, T5>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var t5 = Expression.Parameter(typeof(T5), "t5");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4, t5);
        return Expression.Lambda<Func<T1, T2, T3, T4, T5, TKnownType>>(newExpression, t1, t2, t3, t4, t5).Compile();
    }
    public static Func<T1, T2, T3, T4, TKnownType> New<T1, T2, T3, T4>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var t4 = Expression.Parameter(typeof(T4), "t4");
        var newExpression = Expression.New(ctor, t1, t2, t3, t4);
        return Expression.Lambda<Func<T1, T2, T3, T4, TKnownType>>(newExpression, t1, t2, t3, t4).Compile();
    }
    public static Func<T1, T2, T3, TKnownType> New<T1, T2, T3>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var t3 = Expression.Parameter(typeof(T3), "t3");
        var newExpression = Expression.New(ctor, t1, t2, t3);
        return Expression.Lambda<Func<T1, T2, T3, TKnownType>>(newExpression, t1, t2, t3).Compile();
    }
    public static Func<T1, T2, TKnownType> New<T1, T2>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1), typeof(T2) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var t2 = Expression.Parameter(typeof(T2), "t2");
        var newExpression = Expression.New(ctor, t1, t2);
        return Expression.Lambda<Func<T1, T2, TKnownType>>(newExpression, t1, t2).Compile();
    }
    public static Func<T1, TKnownType> New<T1>(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, new Type[] { typeof(T1) }, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var t1 = Expression.Parameter(typeof(T1), "t1");
        var newExpression = Expression.New(ctor, t1);
        return Expression.Lambda<Func<T1, TKnownType>>(newExpression, t1).Compile();
    }
    public static Func<TKnownType> New(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
    {
        if (t == null) throw new ArgumentNullException(nameof(t));
        if (!typeof(TKnownType).IsAssignableFrom(t)) throw new ArgumentException($"{nameof(TKnownType)} cannot be assigned to from the type provided by {nameof(t)}.", nameof(t));
        var ctor = t.GetConstructor(bindingFlags, Type.DefaultBinder, Type.EmptyTypes, null);
        if (ctor == null)
            throw new ArgumentException(null, nameof(t));
        var newExpression = Expression.New(ctor);
        return Expression.Lambda<Func<TKnownType>>(newExpression).Compile();
    }
}

I'm not including a definition of all 16 parameters with varied ref/out semantics because that would be 316+315...+31 methods and delegates. Adding it up is over 60 million methods/delegates.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜