private static ICollection <MethodInfo> GetConcreteMethods(MethodInfo method, LinkList <Binding> bindings) { Debug.Assert(method != null); Debug.Assert(bindings != null); // Try to resolve generic arguments on method. var openArguments = GenericTypeResolver.GetOpenGenericArguments(method.GetGenericArguments( )); var concreteBindings = new BindingCollection(bindings); GenericTypeResolver.BindGenericArguments(concreteBindings, openArguments); var concreteMethods = concreteBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b)); // If generic arguments cannot be resolved statically, try to bind method arguments by searching for creatable parameter types. if (concreteMethods.Count == 0) { var genericParameterTypes = method.GetParameters( ) .Select(p => p.ParameterType) .Where(t => t.IsGenericType) .ToArray( ); Debug.Assert(genericParameterTypes.All(t => !t.IsGenericParameter)); var creatableParameterTypes = genericParameterTypes .Select(t => TypeCreator.GetCreators(t) .Select(c => c.InstanceType) .Distinct( ) ); var parameterBindings = new BindingCollection(bindings); parameterBindings.Expand(Permuter.Permute(creatableParameterTypes), (b, permutation) => { for (int i = 0; i < permutation.Length; ++i) { Type permutationType = permutation[i]; Type genericParameterType = genericParameterTypes[i]; GenericTypeResolver.GetAssignedGenericArguments(b, permutationType, genericParameterType); } }); concreteMethods = parameterBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b)); } return(concreteMethods); }
private static BindingCollection GetConcreteTypeBindings(Type type, LinkList <Binding> bindings, out LinkList <Type> openArguments) { Debug.Assert(type != null); Debug.Assert(bindings != null); // Avoid recursive searches for generic type. if (type.ContainsGenericParameters) { if (Binding.ContainsType(bindings, type)) { openArguments = LinkList <Type> .Empty; return(new BindingCollection( )); } bindings = bindings.Add(new Binding(null, type)); } // Bind all unassigned generic argument on the generic type. openArguments = GenericTypeResolver.GetOpenGenericArguments(type); var collection = new BindingCollection(bindings); GenericTypeResolver.BindGenericArguments(collection, openArguments); return(collection); }