private static ReadOnlyCollection <Type> GetConcreteTypesCore(Type genericType, LinkList <Binding> bindings) { Debug.Assert(genericType != null); Debug.Assert(bindings != null); bool cached = concreteTypeCache_.ContainsKey(genericType); bool unbound = genericType.GetGenericArguments( ) .All((a) => !Binding.ContainsArgument(bindings, a)); // If the type has already been evaluated and there are no interfering bindings, return cached value. if (cached && unbound) { return(concreteTypeCache_[genericType]); } // Otherwise, get a concrete type for each set of bindings. LinkList <Type> openArguments; BindingCollection concreteTypeBindngs = GenericTypeResolver.GetConcreteTypeBindings(genericType, bindings, out openArguments); var concreteTypes = concreteTypeBindngs .Transform((argumentBindings) => MakeConcreteType(genericType, openArguments, argumentBindings)) .ToReadOnlyCollection( ); // If there are no interfering bindings, cache the concrete types. if (!cached && unbound) { concreteTypeCache_.TryAdd(genericType, concreteTypes); concreteTypes = concreteTypeCache_[genericType]; } return(concreteTypes); }