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); }
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); }