public static TypeReference MakeGenericType (this TypeReference self, params TypeReference [] arguments) { if (self.GenericParameters.Count != arguments.Length) throw new ArgumentException (); var instance = new GenericInstanceType (self); foreach (var argument in arguments) instance.GenericArguments.Add (argument); return instance; }
TypeReference ImportTypeSpecification (TypeReference type, IGenericContext context) { switch (type.etype) { case ElementType.SzArray: var vector = (ArrayType) type; return new ArrayType (ImportType (vector.ElementType, context)); case ElementType.Ptr: var pointer = (PointerType) type; return new PointerType (ImportType (pointer.ElementType, context)); case ElementType.ByRef: var byref = (ByReferenceType) type; return new ByReferenceType (ImportType (byref.ElementType, context)); case ElementType.Pinned: var pinned = (PinnedType) type; return new PinnedType (ImportType (pinned.ElementType, context)); case ElementType.Sentinel: var sentinel = (SentinelType) type; return new SentinelType (ImportType (sentinel.ElementType, context)); case ElementType.CModOpt: var modopt = (OptionalModifierType) type; return new OptionalModifierType ( ImportType (modopt.ModifierType, context), ImportType (modopt.ElementType, context)); case ElementType.CModReqD: var modreq = (RequiredModifierType) type; return new RequiredModifierType ( ImportType (modreq.ModifierType, context), ImportType (modreq.ElementType, context)); case ElementType.Array: var array = (ArrayType) type; return new ArrayType (ImportType (array.ElementType, context), array.Dimensions); case ElementType.GenericInst: var instance = (GenericInstanceType) type; var element_type = ImportType (instance.ElementType, context); var imported_instance = new GenericInstanceType (element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) imported_arguments.Add (ImportType (arguments [i], context)); return imported_instance; case ElementType.Var: if (context == null || context.Type == null) throw new InvalidOperationException (); return ((TypeReference) context.Type).GetElementType ().GenericParameters [((GenericParameter) type).Position]; case ElementType.MVar: if (context == null || context.Method == null) throw new InvalidOperationException (); return context.Method.GenericParameters [((GenericParameter) type).Position]; } throw new NotSupportedException (type.etype.ToString ()); }
public static TypeReference SubstituteTypeArgs(TypeReference type, MemberReference member) { if (type is TypeSpecification) { ArrayType arrayType = type as ArrayType; if (arrayType != null) { TypeReference elementType = SubstituteTypeArgs(arrayType.ElementType, member); if (elementType != arrayType.ElementType) { return new ArrayType(elementType, arrayType.Dimensions); } else { return type; } } ByReferenceType refType = type as ByReferenceType; if (refType != null) { TypeReference elementType = SubstituteTypeArgs(refType.ElementType, member); return elementType != refType.ElementType ? new ByReferenceType(elementType) : type; } GenericInstanceType giType = type as GenericInstanceType; if (giType != null) { GenericInstanceType newType = new GenericInstanceType(giType.ElementType); bool isChanged = false; for (int i = 0; i < giType.GenericArguments.Count; i++) { newType.GenericArguments.Add(SubstituteTypeArgs(giType.GenericArguments[i], member)); isChanged |= newType.GenericArguments[i] != giType.GenericArguments[i]; } return isChanged ? newType : type; } OptionalModifierType optmodType = type as OptionalModifierType; if (optmodType != null) { TypeReference elementType = SubstituteTypeArgs(optmodType.ElementType, member); return elementType != optmodType.ElementType ? new OptionalModifierType(optmodType.ModifierType, elementType) : type; } RequiredModifierType reqmodType = type as RequiredModifierType; if (reqmodType != null) { TypeReference elementType = SubstituteTypeArgs(reqmodType.ElementType, member); return elementType != reqmodType.ElementType ? new RequiredModifierType(reqmodType.ModifierType, elementType) : type; } PointerType ptrType = type as PointerType; if (ptrType != null) { TypeReference elementType = SubstituteTypeArgs(ptrType.ElementType, member); return elementType != ptrType.ElementType ? new PointerType(elementType) : type; } } GenericParameter gp = type as GenericParameter; if (gp != null) { if (gp.Owner.GenericParameterType == GenericParameterType.Method) { return ((GenericInstanceMethod)member).GenericArguments[gp.Position]; } else { if (member.DeclaringType is ArrayType) { return ((ArrayType)member.DeclaringType).ElementType; } else { return ((GenericInstanceType)member.DeclaringType).GenericArguments[gp.Position]; } } } return type; }
TypeReference ImportGenericInstance (Type type, IGenericContext context) { var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition); var instance = new GenericInstanceType (element_type); var arguments = type.GetGenericArguments (); var instance_arguments = instance.GenericArguments; for (int i = 0; i < arguments.Length; i++) instance_arguments.Add (ImportType (arguments [i], context ?? element_type)); return instance; }
static bool AreSame (GenericInstanceType a, GenericInstanceType b) { if (a.GenericArguments.Count != b.GenericArguments.Count) return false; for (int i = 0; i < a.GenericArguments.Count; i++) if (!AreSame (a.GenericArguments [i], b.GenericArguments [i])) return false; return true; }