Exemplo n.º 1
0
        public TypeInstantiation(TypeInstantiationInfo instantiationInfo, TypeInstantiationContext instantiationContext)
            : base(
                ArgumentUtility.CheckNotNull("instantiationInfo", instantiationInfo).GenericTypeDefinition.Name,
                instantiationInfo.GenericTypeDefinition.Namespace,
                instantiationInfo.GenericTypeDefinition.Attributes,
                genericTypeDefinition: instantiationInfo.GenericTypeDefinition,
                typeArguments: instantiationInfo.TypeArguments)
        {
            ArgumentUtility.CheckNotNull("instantiationContext", instantiationContext);

            _instantiationInfo    = instantiationInfo;
            _instantiationContext = instantiationContext;

            var genericTypeDefinition = instantiationInfo.GenericTypeDefinition;
            var declaringType         = genericTypeDefinition.DeclaringType;

            // Even though the _genericTypeDefinition includes the type parameters of the enclosing type(s) (if any), declaringType.GetGenericArguments()
            // will return objects not equal to this type's generic parameters. Since the call to SetDeclaringType below needs to replace the those type
            // parameters with type arguments, add a mapping for the declaring type's generic parameters in addition to this type's generic parameters.

            // ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper is wrong here, declaringType can be null.
            var outerMapping = declaringType != null
          ? declaringType.GetGenericArguments().Zip(instantiationInfo.TypeArguments, Tuple.Create)
          : new Tuple <Type, Type> [0];

            // ReSharper restore ConditionIsAlwaysTrueOrFalse
            var mapping = genericTypeDefinition.GetGenericArguments().Zip(instantiationInfo.TypeArguments, Tuple.Create);

            _parametersToArguments = outerMapping.Concat(mapping).ToDictionary(t => t.Item1, t => t.Item2);

            // Add own instantation to context before substituting any generic parameters.
            instantiationContext.Add(instantiationInfo, this);

            // ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper is wrong here, declaringType can be null.
            if (declaringType != null)
            {
                SetDeclaringType(SubstituteGenericParameters(declaringType));
            }
            // ReSharper restore ConditionIsAlwaysTrueOrFalse
            if (genericTypeDefinition.BaseType != null)
            {
                SetBaseType(SubstituteGenericParameters(genericTypeDefinition.BaseType));
            }

            _nestedTypes  = new Lazy <IReadOnlyCollection <Type> > (() => CreateNestedType().ToList().AsReadOnly());
            _interfaces   = new Lazy <IReadOnlyCollection <Type> > (() => CreateInterfaces().ToList().AsReadOnly());
            _fields       = new Lazy <IReadOnlyCollection <FieldInfo> > (() => CreateFields().Cast <FieldInfo>().ToList().AsReadOnly());
            _constructors = new Lazy <IReadOnlyCollection <ConstructorInfo> > (() => CreateConstructors().Cast <ConstructorInfo>().ToList().AsReadOnly());
            _methods      = new Lazy <IReadOnlyCollection <MethodOnTypeInstantiation> > (() => CreateMethods().ToList().AsReadOnly());
            _properties   = new Lazy <IReadOnlyCollection <PropertyInfo> > (() => CreateProperties().Cast <PropertyInfo>().ToList().AsReadOnly());
            _events       = new Lazy <IReadOnlyCollection <EventInfo> > (() => CreateEvents().Cast <EventInfo>().ToList().AsReadOnly());
        }
Exemplo n.º 2
0
        public Type Instantiate(TypeInstantiationInfo instantiationInfo)
        {
            ArgumentUtility.CheckNotNull("instantiationInfo", instantiationInfo);

            TypeInstantiation typeInstantiation;

            if (_instantiations.TryGetValue(instantiationInfo, out typeInstantiation))
            {
                return(typeInstantiation);
            }

            var genTypeDef = instantiationInfo.GenericTypeDefinition;
            var typeArgs   = instantiationInfo.TypeArguments;

            if (genTypeDef.IsRuntimeType() && typeArgs.All(a => a.IsRuntimeType()))
            {
                return(genTypeDef.MakeGenericType(typeArgs.ToArray()));
            }

            return(new TypeInstantiation(instantiationInfo, this));
        }
Exemplo n.º 3
0
        public Type SubstituteGenericParameters(Type type, IDictionary <Type, Type> parametersToArguments)
        {
            ArgumentUtility.CheckNotNull("type", type);
            ArgumentUtility.CheckNotNull("parametersToArguments", parametersToArguments);

            Type typeArgument;

            if (parametersToArguments.TryGetValue(type, out typeArgument))
            {
                return(Assertion.IsNotNull(typeArgument, "Type-argument for type-parameter '{0}' was null.", type));
            }

            if (type.IsArray)
            {
                return(SubstituteArrayElementType(type, parametersToArguments));
            }
            if (type.IsByRef)
            {
                return(SubstituteByRefElementType(type, parametersToArguments));
            }
            if (!type.IsGenericType)
            {
                return(type);
            }

            var oldTypeArguments = type.GetGenericArguments();
            var newTypeArguments = oldTypeArguments.Select(t => SubstituteGenericParameters(t, parametersToArguments)).ToList();

            // No substitution necessary (this is an optimization only).
            if (oldTypeArguments.SequenceEqual(newTypeArguments))
            {
                return(type);
            }

            var genericTypeDefinition = type.GetGenericTypeDefinition();
            var instantiationInfo     = new TypeInstantiationInfo(genericTypeDefinition, newTypeArguments);

            return(Instantiate(instantiationInfo));
        }