Esempio n. 1
0
        /// <summary>
        /// Creates a generic method using given arguments.
        /// </summary>
        /// <returns>The generic method.</returns>
        static MethodInfo CreateGenericMethod(VariableTBase[] args, Invokable iv)
        {
            var pseinfo = iv.MInfo.GetParameters();
            int mlength = pseinfo.Length;

            if (iv.CallStd.cfunc)
            {
                mlength--;
            }
            if (iv.CallStd.hp1)
            {
                mlength--;
            }
            if (iv.CallStd.hp2)
            {
                mlength--;
            }
            Type[] stype = iv.MInfo.GetGenericArguments();
            List <Tuple <Type, Type> > typerelist = new List <Tuple <Type, Type> > ();
            int i;

            for (i = 0; i < mlength; i++)
            {
                ParameterInfo pinf   = pseinfo[i];
                bool          hasGen = pinf.ParameterType.ContainsGenericParameters;
                if (!hasGen)
                {
                    continue;
                }
                if (hasGen)
                {
                    List <Tuple <Type, Type> > ntp = TypeInference.ReplacementTypes(args[i].GetType(), pinf.ParameterType);
                    if (ntp == null)
                    {
                        throw new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.GenericFunctionArgumentsMismatch);
                    }
                    typerelist.AddRange(ntp);
                }
            }
            if (iv.CallStd.hp1 | iv.CallStd.hp2)
            {
                if (pseinfo[mlength].ParameterType.ContainsGenericParameters)
                {
                    Type vt = args[mlength].GetType().GetGenericArguments()[0];
                    for (i = mlength + 1; i < args.Length; i++)
                    {
                        Type rt = args[i].GetType().GetGenericArguments()[0];
                        vt = TypeInference.GetCommonBaseClass(vt, rt);
                    }
                    List <Tuple <Type, Type> > ntp = TypeInference.ReplacementTypes(typeof(Variable <>).MakeGenericType(vt), pseinfo[mlength].ParameterType.GetElementType());
                    if (ntp == null)
                    {
                        throw new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.GenericFunctionArgumentsMismatch);
                    }
                    typerelist.AddRange(ntp);
                }
            }
            Type[] relist = new Type[stype.Length];
            for (i = 0; i < stype.Length; i++)
            {
                relist[i] = typerelist.Find((Tuple <Type, Type> obj) => obj.Item2 == stype[i]).Item1;
            }

            MethodInfo minf = iv.MInfo.MakeGenericMethod(relist);

            return(minf);
        }