vendredi 7 août 2015

dynamicly create delegate for ctor

I'm trying to create generic factory class. Since Activator.CreateInstance is pretty slow, I decided to use delegates. The goal was call constructor any public constructor, regardless of parameters count. So I was going like this:

public void Register<VType>(TKey key, params object[] args) where VType : TType
    {
        ConstructorInfo ci = typeof(VType).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.HasThis, args.Select(a => a.GetType()).ToArray(), new ParameterModifier[] { });
        if (ci == null)
            throw new InvalidOperationException(string.Format("Constructor for type '{0}' was not found.", typeof(VType)));


        var pExp = Expression.Parameter(args.GetType());
        var ctorParams = ci.GetParameters();
        var expArr = new Expression[ctorParams.Length];
        var p = new ParameterExpression[ctorParams.Length];

        for (var i = 0; i < ctorParams.Length; i++)
        {
            var ctorType = ctorParams[i].ParameterType;
            var pName = ctorParams[i].Name;
            var argExp = Expression.ArrayIndex(pExp, Expression.Constant(i));
            var argExpConverted = Expression.Convert(argExp, ctorType);
            expArr[i] = argExpConverted;
            p[i] = Expression.Parameter(args[i].GetType(), pName);
        }

        var foo = Expression.Lambda(Expression.New(ci, expArr), p);

        Delegate constructorDelegate = foo.Compile();

        FactoryMap.Add(key, constructorDelegate);
    }

And then - call delegate in Create method. With no parameters all goes well, but when I'm adding some - I'm getting InvalidOperationException - "variable '' of type 'System.Object[]' referenced from scope '', but it is not defined", after foo.Compile() call. Why? How can I resolve this issue?





Aucun commentaire:

Enregistrer un commentaire