public override Type[] InferDelegateArguments (MethodBase method) { AParametersCollection pd = TypeManager.GetParameterData (method); if (arg_count != pd.Count) return null; Type[] d_gargs = method.GetGenericArguments (); TypeInferenceContext context = new TypeInferenceContext (d_gargs); // A lower-bound inference is made from each argument type Uj of D // to the corresponding parameter type Tj of M for (int i = 0; i < arg_count; ++i) { Type t = pd.Types [i]; if (!t.IsGenericParameter) continue; context.LowerBoundInference ((Type)arguments[i], t); } if (!context.FixAllTypes ()) return null; return context.InferredTypeArguments; }
// // Implements method type arguments inference // bool InferInPhases (ResolveContext ec, TypeInferenceContext tic, AParametersCollection methodParameters) { int params_arguments_start; if (methodParameters.HasParams) { params_arguments_start = methodParameters.Count - 1; } else { params_arguments_start = arg_count; } TypeSpec [] ptypes = methodParameters.Types; // // The first inference phase // TypeSpec method_parameter = null; for (int i = 0; i < arg_count; i++) { Argument a = arguments [i]; if (a == null) continue; if (i < params_arguments_start) { method_parameter = methodParameters.Types [i]; } else if (i == params_arguments_start) { if (arg_count == params_arguments_start + 1 && TypeManager.HasElementType (a.Type)) method_parameter = methodParameters.Types [params_arguments_start]; else method_parameter = TypeManager.GetElementType (methodParameters.Types [params_arguments_start]); ptypes = (TypeSpec[]) ptypes.Clone (); ptypes [i] = method_parameter; } // // When a lambda expression, an anonymous method // is used an explicit argument type inference takes a place // AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression; if (am != null) { if (am.ExplicitTypeInference (ec, tic, method_parameter)) --score; continue; } if (a.IsByRef) { score -= tic.ExactInference (a.Type, method_parameter); continue; } if (a.Expr.Type == InternalType.Null) continue; if (TypeManager.IsValueType (method_parameter)) { score -= tic.LowerBoundInference (a.Type, method_parameter); continue; } // // Otherwise an output type inference is made // score -= tic.OutputTypeInference (ec, a.Expr, method_parameter); } // // Part of the second phase but because it happens only once // we don't need to call it in cycle // bool fixed_any = false; if (!tic.FixIndependentTypeArguments (ec, ptypes, ref fixed_any)) return false; return DoSecondPhase (ec, tic, ptypes, !fixed_any); }