public TypeReference Visit(GenericInstanceType current, IGenericContext gcontext) { var elementType = Get(current.GetElementType(), gcontext); var result = new GenericInstanceType(elementType); if (current.HasGenericArguments) { foreach (var ga in current.GenericArguments) { result.GenericArguments.Add(Get(ga, gcontext /*elementType*/)); } } return(result); }
/// <summary> /// Resolves the <see cref="Type"/> of the given <see cref="GenericInstanceType"/> recursively. /// </summary> /// <param name="throwError"> /// Whether the method should throw an error if the <see cref="Type"/> cannot be resolved. /// </param> public Type GetGenericType(GenericInstanceType genericInstanceType, bool throwError = false) { var genericType = GetType(genericInstanceType.GetElementType().FullName); var genericTypeArgs = new List <Type>(); foreach (var parameter in genericInstanceType.GenericArguments.ToList()) { if (parameter.IsGenericInstance) { genericTypeArgs.Add(GetGenericType((GenericInstanceType)parameter, throwError)); } else { genericTypeArgs.Add(GetType(parameter.FullName, throwError)); } } return(genericType.MakeGenericType(genericTypeArgs.ToArray())); }
static void ProcessMethod(MethodDefinition method, HashSet <TypeReference> typeset) { // this is needed in case we return an enum, a struct or something mapped // to p/invoke (i.e. no ctor called). We also need to check for arrays. TypeReference t = method.ReturnType; AddType(typeset, t); if (method.HasParameters) { // an "out" from a p/invoke must be flagged foreach (ParameterDefinition parameter in method.Parameters) { // we don't want the reference (&) on the type t = parameter.ParameterType.GetElementType(); AddType(typeset, t); } } if (!method.HasBody) { return; } MethodBody body = method.Body; if (body.HasVariables) { // add every type of variables we use foreach (VariableDefinition variable in body.Variables) { t = variable.VariableType; AddType(typeset, t); } } // add every type we create or refer to (e.g. loading fields from an enum) foreach (Instruction ins in body.Instructions) { if (ins.Operand == null) { continue; } t = ins.Operand as TypeReference; if (t == null) { MethodReference m = ins.Operand as MethodReference; if (m != null) { t = m.DeclaringType; GenericInstanceType generic = (t as GenericInstanceType); if (generic != null) { t = generic.GetElementType(); } } else { FieldReference f = ins.Operand as FieldReference; if (f != null) { t = f.DeclaringType; } } } if (t != null) { AddType(typeset, t); } } }