Example #1
0
        // Private methods ------------------------------------------------------------------

        private static object Call(Type type, object target, string name, object[] argValues)
        {
            var nbOfProvidedArgs = 0;

            if (argValues != null)
            {
                nbOfProvidedArgs = argValues.Length;
            }

            // Check if it is a field name
            var fi = type.GetField(name);

            if (fi != null)
            {
                if (nbOfProvidedArgs > 0)
                {
                    if (nbOfProvidedArgs == 1)
                    {
                        fi.SetValue(target, argValues[0]);
                        return(null);
                    }
                    else
                    {
                        throw new TargetException(nbOfProvidedArgs + " argument(s) provided for field " + target + "." + name + " when 1 expected");
                    }
                }
                else
                {
                    return(fi.GetValue(target));
                }
            }

            // Check if it is a property name
            MethodInfo   mi = null;
            PropertyInfo pi;

            if (nbOfProvidedArgs > 0)
            {
                // If we have arguments passed, try to locate a property mathing those
                pi = type.GetProperty(name, GetArgumentTypes(argValues));
                if (pi != null)
                {
                    // If the property is found, give priority to getter
                    // This is of course a limitation, for very specific things
                    // NxBRE users will enjoy implementing code delegates!
                    mi = pi.GetGetMethod();
                    if (mi == null)
                    {
                        mi = pi.GetSetMethod();
                    }
                }
                else
                {
                    // If the property is found, try to find a basic non-argument property
                    // and target the set method as we have arguments passed
                    pi = type.GetProperty(name);
                    if (pi != null)
                    {
                        mi = pi.GetSetMethod();
                    }
                }
            }
            else
            {
                // Having no arguments passed, we clearly want a getter.
                pi = type.GetProperty(name);
                if (pi != null)
                {
                    mi = pi.GetGetMethod();
                }
            }

            // check if it is a method name
            var types = GetArgumentTypes(argValues);

            if (mi == null)
            {
                mi = type.GetMethod(name, types);
            }

            // let's try by group the identical arguments of same types to try them as a param array
            if (mi == null)
            {
                var reArgValues = Parameter.GroupFinal(argValues);
                if (!Array.ReferenceEquals(argValues, reArgValues))
                {
                    types = GetArgumentTypes(reArgValues);
                    mi    = type.GetMethod(name, types);
                    if (mi != null)
                    {
                        argValues = reArgValues;
                    }
                }
            }

            // the last option is to try to find if there is a single method with the desired name
            if (mi == null)
            {
                try
                {
                    mi = type.GetMethod(name);
                }
                catch (AmbiguousMatchException)
                {
                    // IGNORED
                }
            }

            // if something has been found

            if (mi == null)
            {
                return(CallMethodWithByRefParametersOrThrow(type,
                                                            target,
                                                            name,
                                                            argValues,
                                                            new TargetException("Can not find member " + type.FullName
                                                                                + "." + name
                                                                                + Misc.ArrayToString(types)
                                                                                + " for values "
                                                                                + Misc.ArrayToString(argValues))));
            }
            {
                // if the number of arguments match, perform the invocation
                if (argValues != null && argValues.Length == mi.GetParameters().Length)
                {
                    return(mi.Invoke(target, argValues));
                }
                // try a last trick by grouping the last arguments in an array
                // in order to reach the right number of arguments
                var reArgValues = Parameter.GroupFinal(argValues,
                                                       mi.GetParameters().Length,
                                                       mi.GetParameters()[mi.GetParameters().Length - 1].ParameterType);
                return(mi.Invoke(target, reArgValues));
            }

            // nothing found
        }