Exemple #1
0
        /// <summary>
        /// Resolves a method by its name and argument types. If generic arguments are passed, they are also applied.
        /// Generic arguments whose values can be inferred from argument types can be skipped.
        /// </summary>
        public MethodWrapper ResolveMethod(Type type, string name, Type[] argTypes, Type[] hints = null, LambdaResolver resolver = null)
        {
            if (!(type is TypeBuilder))
            {
                return(ReflectionHelper.ResolveMethod(type, name, argTypes, hints, resolver));
            }

            var typeEntity = _definedTypes[type.Name];

            try
            {
                var method = typeEntity.ResolveMethod(name, argTypes);
                var mw     = WrapMethod(method, ReflectionHelper.IsPartiallyApplied(argTypes));

                var isGeneric = method.IsImported && method.MethodInfo.IsGenericMethod;
                if (isGeneric)
                {
                    var argTypeDefs   = method.MethodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
                    var genericDefs   = method.MethodInfo.GetGenericArguments();
                    var genericValues = GenericHelper.ResolveMethodGenericsByArgs(argTypeDefs, argTypes, genericDefs, hints, resolver);

                    mw.MethodInfo       = method.MethodInfo.MakeGenericMethod(genericValues);
                    mw.ArgumentTypes    = method.GetArgumentTypes(this).Select(t => GenericHelper.ApplyGenericArguments(t, genericDefs, genericValues)).ToArray();
                    mw.GenericArguments = genericValues;
                    mw.ReturnType       = GenericHelper.ApplyGenericArguments(method.MethodInfo.ReturnType, genericDefs, genericValues);
                }
                else
                {
                    if (hints != null)
                    {
                        Error(CompilerMessages.GenericArgsToNonGenericMethod, name);
                    }
                }

                return(mw);
            }
            catch (KeyNotFoundException)
            {
                return(ResolveMethod(type.BaseType, name, argTypes, hints));
            }
        }