예제 #1
0
        /// <summary>
        /// Substitute references to type parameters from 'typeDef'
        /// with type arguments from 'typeArgs' in type 'type'.
        /// </summary>
        internal static Type Substitute(this Type type, Type typeDef, Type[] typeArgs)
        {
            Debug.Assert(typeDef.IsGenericTypeDefinition);
            Debug.Assert(typeDef.GetGenericArguments().Length == typeArgs.Length);

            if (type.IsGenericType)
            {
                var builder = ArrayBuilder <Type> .GetInstance();

                foreach (var t in type.GetGenericArguments())
                {
                    builder.Add(t.Substitute(typeDef, typeArgs));
                }
                var typeDefinition = type.GetGenericTypeDefinition();
                return(typeDefinition.MakeGenericType(builder.ToArrayAndFree()));
            }
            else if (type.IsArray)
            {
                var elementType = type.GetElementType();
                elementType = elementType.Substitute(typeDef, typeArgs);
                var n = type.GetArrayRank();
                return((n == 1) ? elementType.MakeArrayType() : elementType.MakeArrayType(n));
            }
            else if (type.IsPointer)
            {
                var elementType = type.GetElementType();
                elementType = elementType.Substitute(typeDef, typeArgs);
                return(elementType.MakePointerType());
            }
            else if (type.IsGenericParameter)
            {
                if (type.DeclaringType.Equals(typeDef))
                {
                    var ordinal = type.GenericParameterPosition;
                    return(typeArgs[ordinal]);
                }
            }

            return(type);
        }