コード例 #1
0
        private MethodInfo GetMethodImplCommon(
            String name, int genericParameterCount, BindingFlags bindingAttr, Binder binder, CallingConventions callConv,
            Type [] types, ParameterModifier [] modifiers)
        {
            ListBuilder <MethodInfo> candidates = GetMethodCandidates(name, genericParameterCount, bindingAttr, callConv, types, false);

            if (candidates.Count == 0)
            {
                return(null);
            }

            if (types == null || types.Length == 0)
            {
                MethodInfo firstCandidate = candidates[0];

                if (candidates.Count == 1)
                {
                    return(firstCandidate);
                }
                else if (types == null)
                {
                    for (int j = 1; j < candidates.Count; j++)
                    {
                        MethodInfo methodInfo = candidates [j];
                        if (!System.DefaultBinder.CompareMethodSig(methodInfo, firstCandidate))
                        {
                            throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
                        }
                    }

                    // All the methods have the exact same name and sig so return the most derived one.
                    return(System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo);
                }
            }

            if (binder == null)
            {
                binder = DefaultBinder;
            }

            return(binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo);
        }
コード例 #2
0
        public static object CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            // If they didn't specify a lookup, then we will provide the default lookup.
            const BindingFlags LookupMask = (BindingFlags)0x000000FF;

            if ((bindingAttr & LookupMask) == 0)
            {
                bindingAttr |= BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
            }

            if (activationAttributes != null && activationAttributes.Length > 0)
            {
                throw new PlatformNotSupportedException(SR.NotSupported_ActivAttr);
            }

            type = type.UnderlyingSystemType;
            CreateInstanceCheckType(type);

            if (args == null)
            {
                args = Array.Empty <object>();
            }
            int numArgs = args.Length;

            // This short-circuit depends on the fact that the toolchain prohibits valuetypes with nullary constructors. Unfortunately, we can't check for the presence of nullary
            // constructors without risking a MissingMetadataException, and we can't regress the prior N behavior that allowed CreateInstance on valuetypes to work regardless of metadata.
            if (numArgs == 0 && type.IsValueType)
            {
                return(RuntimeAugments.NewObject(type.TypeHandle));
            }

            Type[] argTypes = new Type[numArgs];
            for (int i = 0; i < numArgs; i++)
            {
                argTypes[i] = args[i]?.GetType();
            }

            ConstructorInfo[]        candidates = type.GetConstructors(bindingAttr);
            ListBuilder <MethodBase> matches    = new ListBuilder <MethodBase>(candidates.Length);

            for (int i = 0; i < candidates.Length; i++)
            {
                if (candidates[i].QualifiesBasedOnParameterCount(bindingAttr, CallingConventions.Any, argTypes))
                {
                    matches.Add(candidates[i]);
                }
            }
            if (matches.Count == 0)
            {
                throw new MissingMethodException(SR.Arg_NoDefCTor);
            }

            if (binder == null)
            {
                binder = Type.DefaultBinder;
            }

            object     state        = null;
            MethodBase invokeMethod = binder.BindToMethod(bindingAttr, matches.ToArray(), ref args, null, culture, null, out state);

            if (invokeMethod.GetParametersNoCopy().Length == 0)
            {
                if (args.Length != 0)
                {
                    Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs);
                    throw new NotSupportedException(SR.NotSupported_CallToVarArg);
                }

                // Desktop compat: CoreClr invokes a "fast-path" here (call Activator.CreateInstance(type, true)) that also
                // bypasses the binder.ReorderArgumentArray() call. That "fast-path" isn't a fast-path for us so we won't do that
                // but we'll still null out the "state" variable to bypass the Reorder call.
                //
                // The only time this matters at all is if (1) a third party binder is being used and (2) it actually reordered the array
                // which it shouldn't have done because (a) we didn't request it to bind arguments by name, and (b) it's kinda hard to
                // reorder a zero-length args array. But who knows what a third party binder will do if we make a call to it that we didn't
                // used to do, so we'll preserve the CoreClr order of calls just to be safe.
                state = null;
            }

            object result = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            if (state != null)
            {
                binder.ReorderArgumentArray(ref args, state);
            }
            return(result);
        }