private static void CanonicalTypeRefName(Type type, StringBuilder sb, IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> decoder) { if (decoder.IsArray(type)) { CanonicalTypeRefName(decoder.ElementType(type), sb, decoder); sb.Append("[]"); return; } if (decoder.IsManagedPointer(type)) { sb.Append("ref "); CanonicalTypeRefName(decoder.ElementType(type), sb, decoder); return; } if (decoder.IsFormalTypeParameter(type)) { sb.Append(decoder.Name(type)); return; } if (decoder.IsMethodFormalTypeParameter(type)) { sb.Append(decoder.Name(type)); return; } IIndexable <Type> typeArgs; if (decoder.IsSpecialized(type, out typeArgs)) { CanonicalTypeRefName(decoder.Unspecialized(type), sb, decoder); sb.Append('<'); for (int i = 0; i < typeArgs.Count; i++) { CanonicalTypeRefName(typeArgs[i], sb, decoder); if (i < typeArgs.Count - 1) { sb.Append(','); } } return; } if (decoder.IsUnmanagedPointer(type)) { CanonicalTypeRefName(decoder.ElementType(type), sb, decoder); sb.Append("*"); return; } Type modified; IIndexable <Pair <bool, Type> > modifiers; if (decoder.IsModified(type, out modified, out modifiers)) { CanonicalTypeRefName(modified, sb, decoder); for (int i = 0; i < modifiers.Count; i++) { if (modifiers[i].One) { sb.Append(" opt("); } else { sb.Append(" req("); } CanonicalTypeRefName(modifiers[i].Two, sb, decoder); sb.Append(')'); } return; } CanonicalTypeDefName(type, sb, decoder); }