コード例 #1
0
        internal static Expression InvokeMethod(MethodInfo mi, DynamicMetaObject target, DynamicMetaObject[] args, bool expandParameters)
        {
            Expression expression;
            List <ParameterExpression> parameterExpressions = new List <ParameterExpression>();
            List <Expression>          expressions          = new List <Expression>();
            var temps     = new List <ParameterExpression>();
            var initTemps = new List <Expression>();
            List <Expression> expressions1 = new List <Expression>();

            ParameterInfo[] parameters      = mi.GetParameters();
            Expression[]    expressionArray = new Expression[(int)parameters.Length];
            for (int i = 0; i < (int)parameters.Length; i++)
            {
                string name      = parameters[i].Name;
                var    paramName = parameters[i].Name;
                if (string.IsNullOrWhiteSpace(parameters[i].Name))
                {
                    paramName = i.ToString(CultureInfo.InvariantCulture);
                }
                if ((int)parameters[i].GetCustomAttributes(typeof(ParamArrayAttribute), false).Length == 0)
                {
                    if (i < (int)args.Length)
                    {
                        if (!parameters[i].ParameterType.IsByRef)
                        {
                            expressionArray[i] = args[i].CastOrConvertMethodArgument(parameters[i].ParameterType, paramName, mi.Name, temps, initTemps);
                        }
                        else
                        {
                            if (args[i].Value as PSReference != null)
                            {
                                ParameterExpression parameterExpression = Expression.Variable(parameters[i].ParameterType.GetElementType());
                                temps.Add(parameterExpression);
                                MemberExpression memberExpression = Expression.Property(args[i].Expression.Cast(typeof(PSReference)), CachedReflectionInfo.PSReference_Value);
                                initTemps.Add(Expression.Assign(parameterExpression, memberExpression.Convert(parameterExpression.Type)));
                                expressions1.Add(Expression.Assign(memberExpression, parameterExpression.Cast(typeof(object))));
                                expressionArray[i] = parameterExpression;
                            }
                            else
                            {
                                Type[] typeArray = new Type[4];
                                typeArray[0] = typeof(string);
                                typeArray[1] = typeof(Exception);
                                typeArray[2] = typeof(string);
                                typeArray[3] = typeof(object[]);
                                object[] nonRefArgumentToRefParameter = new object[4];
                                nonRefArgumentToRefParameter[0] = "NonRefArgumentToRefParameterMsg";
                                nonRefArgumentToRefParameter[2] = ExtendedTypeSystem.NonRefArgumentToRefParameter;
                                object[] fullName = new object[3];
                                fullName[0] = i + 1;
                                fullName[1] = typeof(PSReference).FullName;
                                fullName[2] = "[ref]";
                                nonRefArgumentToRefParameter[3] = fullName;
                                return(Compiler.CreateThrow(typeof(object), typeof(MethodException), typeArray, nonRefArgumentToRefParameter));
                            }
                        }
                    }
                    else
                    {
                        object defaultValue = parameters[i].DefaultValue;
                        if (defaultValue != null)
                        {
                            expressionArray[i] = Expression.Constant(defaultValue);
                        }
                        else
                        {
                            expressionArray[i] = Expression.Constant(null, parameters[i].ParameterType);
                        }
                    }
                }
                else
                {
                    Func <DynamicMetaObject, Expression> func = null;
                    Type elementType = parameters[i].ParameterType.GetElementType();
                    if (!expandParameters)
                    {
                        Expression expression1 = args[i].CastOrConvertMethodArgument(parameters[i].ParameterType, paramName, mi.Name, temps, initTemps);
                        expressionArray[i] = expression1;
                    }
                    else
                    {
                        Expression[] expressionArray1 = expressionArray;
                        int          num  = i;
                        Type         type = elementType;
                        IEnumerable <DynamicMetaObject> dynamicMetaObjects = args.Skip <DynamicMetaObject>(i);
                        if (func == null)
                        {
                            func = (DynamicMetaObject a) => a.CastOrConvertMethodArgument(elementType, name, mi.Name, parameterExpressions, expressions);
                        }
                        expressionArray1[num] = Expression.NewArrayInit(type, dynamicMetaObjects.Select <DynamicMetaObject, Expression>(func));
                    }
                }
            }
            if (mi.IsStatic)
            {
                expression = Expression.Call(mi, expressionArray);
            }
            else
            {
                expression = Expression.Call(PSGetMemberBinder.GetTargetExpr(target).Cast(mi.DeclaringType), mi, expressionArray);
            }
            Expression expression2 = expression;

            if (temps.Any <ParameterExpression>())
            {
                if (!mi.ReturnType.Equals(typeof(void)) && expressions1.Any <Expression>())
                {
                    ParameterExpression parameterExpression1 = Expression.Variable(mi.ReturnType);
                    temps.Add(parameterExpression1);
                    expression2 = Expression.Assign(parameterExpression1, expression2);
                    expressions1.Add(parameterExpression1);
                }
                expression2 = Expression.Block(mi.ReturnType, temps, initTemps.Append <Expression>(expression2).Concat <Expression>(expressions1));
            }
            return(expression2);
        }