예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #4
0
        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);
        }
예제 #7
0
        /// <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));
        }