public static MethodDeclaration CreateEquivalent(MethodInfo method) { ArgumentUtility.CheckNotNull("method", method); if (method.IsGenericMethodInstantiation()) { throw new ArgumentException( "The specified method must be either a non-generic method or a generic method definition; it cannot be a method instantiation.", "method"); } var oldGenericParameters = method.GetGenericArguments(); var instantiationContext = new TypeInstantiationContext(); var genericParameters = oldGenericParameters.Select(g => CreateEquivalentGenericParameter(g, oldGenericParameters, instantiationContext)); Func <GenericParameterContext, Type> returnTypeProvider = ctx => { var parametersToArguments = oldGenericParameters.Zip(ctx.GenericParameters, Tuple.Create).ToDictionary(t => t.Item1, t => t.Item2); return(instantiationContext.SubstituteGenericParameters(method.ReturnType, parametersToArguments)); }; Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider = ctx => { var parametersToArguments = oldGenericParameters.Zip(ctx.GenericParameters, Tuple.Create).ToDictionary(t => t.Item1, t => t.Item2); return(method.GetParameters().Select(p => CreateEquivalentParameter(p, parametersToArguments, instantiationContext))); }; return(new MethodDeclaration(genericParameters, returnTypeProvider, parameterProvider)); }
private static ParameterDeclaration CreateEquivalentParameter( ParameterInfo parameter, IDictionary <Type, Type> parametersToArguments, TypeInstantiationContext instantiationContext) { var type = instantiationContext.SubstituteGenericParameters(parameter.ParameterType, parametersToArguments); return(new ParameterDeclaration(type, parameter.Name, parameter.Attributes)); }
public void Instantiate_AlreadyInContext() { var instantiation = _context.Instantiate(_info); var result1 = _context.Instantiate(_info); var result2 = new TypeInstantiationContext().Instantiate(_info); Assert.That(result1, Is.SameAs(instantiation)); Assert.That(result2, Is.Not.SameAs(instantiation)); }
private static GenericParameterDeclaration CreateEquivalentGenericParameter( Type genericParameter, IEnumerable <Type> oldGenericParameters, TypeInstantiationContext instantiationContext) { Func <GenericParameterContext, IEnumerable <Type> > constraintProvider = ctx => { var parametersToArguments = oldGenericParameters.Zip(ctx.GenericParameters, Tuple.Create).ToDictionary(t => t.Item1, t => t.Item2); return(genericParameter.GetGenericParameterConstraints() .Where(g => g != typeof(ValueType)) .Select(c => instantiationContext.SubstituteGenericParameters(c, parametersToArguments))); }; return(new GenericParameterDeclaration(genericParameter.Name, genericParameter.GenericParameterAttributes, constraintProvider)); }
public void SetUp() { _context = new TypeInstantiationContext(); _genericTypeDefinition = typeof(List <>); _customType = CustomTypeObjectMother.Create(); _info = new TypeInstantiationInfo(_genericTypeDefinition, new[] { _customType }.AsOneTime()); _parameter = typeof(GenericType <>).GetGenericArguments().Single(); _argument = ReflectionObjectMother.GetSomeType(); _parametersToArguments = new Dictionary <Type, Type> { { _parameter, _argument } }; }
public static TypeInstantiation Create( Type genericTypeDefinition = null, IEnumerable <Type> typeArguments = null, TypeInstantiationContext instantiationContext = null, IMemberSelector memberSelector = null) { genericTypeDefinition = genericTypeDefinition ?? typeof(MyGenericType <>); typeArguments = typeArguments ?? genericTypeDefinition.GetGenericArguments().Select(a => ReflectionObjectMother.GetSomeType()); var instantiationInfo = new TypeInstantiationInfo(genericTypeDefinition, typeArguments); instantiationContext = instantiationContext ?? new TypeInstantiationContext(); memberSelector = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator()); var typeInstantiation = new TypeInstantiation(instantiationInfo, instantiationContext); typeInstantiation.SetMemberSelector(memberSelector); return(typeInstantiation); }
/// <summary> /// Substitutes the type parameters of the generic type definition and returns a <see cref="Type"/> object representing the resulting /// constructed generic type. Use this as a replacement for <see cref="Type.MakeGenericType"/>. /// </summary> /// <param name="genericTypeDefinition">The generic type definition.</param> /// <param name="typeArguments">The type arguments.</param> /// <returns>The generic type instantiation.</returns> public static Type MakeTypePipeGenericType(this Type genericTypeDefinition, params Type[] typeArguments) { ArgumentUtility.CheckNotNull("typeArguments", typeArguments); ArgumentUtility.CheckNotNullOrItemsNull("typeArguments", typeArguments); if (!genericTypeDefinition.IsGenericTypeDefinition) { var message = string.Format( "'{0}' is not a generic type definition. {1} may only be called on a type for which Type.IsGenericTypeDefinition is true.", genericTypeDefinition.Name, MethodInfo.GetCurrentMethod().Name); throw new InvalidOperationException(message); } var typeParameters = genericTypeDefinition.GetGenericArguments(); GenericArgumentUtility.ValidateGenericArguments(typeParameters, typeArguments, genericTypeDefinition.Name); var instantiationContext = new TypeInstantiationContext(); var instantiationInfo = new TypeInstantiationInfo(genericTypeDefinition, typeArguments); return(instantiationContext.Instantiate(instantiationInfo)); }