Obtenez GenericType-Name au bon format en utilisant Reflection on C #

Je dois obtenir le nom de generic-type sous la forme de sa déclaration en code.

Par exemple: Pour la liste , je souhaite obtenir la chaîne “List “. La propriété standard Type.Name renvoie “List`1” dans cette situation.

EDIT: l’exemple a été corrigé

Ok, j’ai fait beaucoup de recherches et découvert que typeof (List) a “GetGenericArguments” qui vous donnera les noms secondaires. Donc, je le ferais de cette façon (pour 1 type générique, s’il s’agit d’un multi, il faudra une boucle ou autre chose. Je peux poster une fonction pour cela si demandé.

Voici une fonction pour le faire avec plusieurs arguments génériques, des types génériques “nesteds”. Edité à nouveau pour utiliser la fonction Aggregate:

static ssortingng GetFullName(Type t) { if (!t.IsGenericType) return t.Name; SsortingngBuilder sb=new SsortingngBuilder(); sb.Append(t.Name.Subssortingng(0, t.Name.LastIndexOf("`"))); sb.Append(t.GetGenericArguments().Aggregate("<", delegate(string aggregate,Type type) { return aggregate + (aggregate == "<" ? "" : ",") + GetFullName(type); } )); sb.Append(">"); return sb.ToSsortingng(); } 

En utilisant les fonctions intégrées et Linq cela peut être écrit

 static ssortingng PrettyTypeName(Type t) { if (t.IsGenericType) { return ssortingng.Format( "{0}<{1}>", t.Name.Subssortingng(0, t.Name.LastIndexOf("`", SsortingngComparison.InvariantCulture)), ssortingng.Join(", ", t.GetGenericArguments().Select(PrettyTypeName))); } return t.Name; } 

REMARQUE: dans une version antérieure de C #, le compilateur nécessite explicitement .ToArray() :

  ssortingng.Join(", ", t.GetGenericArguments().Select(PrettyTypeName).ToArray())); 

Ce n’est pas trop difficile. 😉

Ok, je vais mordre … g Celui ci-dessous fonctionne de manière récursive et affiche les types primitifs sans espace de nom (comme l’OP a écrit):

  static ssortingng PrettyPrintGenericTypeName(Type typeRef) { var rootType = typeRef.IsGenericType ? typeRef.GetGenericTypeDefinition() : typeRef; var cleanedName = rootType.IsPrimitive ? rootType.Name : rootType.ToSsortingng(); if (!typeRef.IsGenericType) return cleanedName; else return cleanedName.Subssortingng(0, cleanedName.LastIndexOf('`')) + typeRef.GetGenericArguments() .Aggregate("<", (r, i) => r + (r != "<" ? ", " : null) + PrettyPrintGenericTypeName(i)) + ">"; } 

Le nom de nettoyage ainsi obtenu ressemble à ceci: System.Collections.Generic.Dictionary, ConsoleApplication2.Program+SomeType>

Un autre exemple que je viens d’écrire avant de trébucher.

  private ssortingng PrettyPrintGenericTypeName(Type p) { if (p.IsGenericType) { var simpleName = p.Name.Subssortingng(0, p.Name.IndexOf('`')); var genericTypeParams = p.GenericTypeArguments.Select(PrettyPrintGenericTypeName).ToList(); return ssortingng.Format("{0}<{1}>", simpleName, ssortingng.Join(", ", genericTypeParams)); } else { return p.Name; } } 

Vieille question, mais j’en ai seulement besoin aujourd’hui. J’ai donc écrit une méthode d’extension capable de générer un joli nom générique au format C # pouvant gérer des types génériques nesteds à plusieurs niveaux.

 using System; using System.Text; public static class TypeExtensions { public static ssortingng GetNiceName(this Type type, bool useFullName = false) { if (!type.IsGenericType) { return type.Name; } var typeNameBuilder = new SsortingngBuilder(); GetNiceGenericName(typeNameBuilder, type, useFullName); return typeNameBuilder.ToSsortingng(); } static void GetNiceGenericName(SsortingngBuilder sb, Type type, bool useFullName) { if (!type.IsGenericType) { sb.Append(useFullName ? type.FullName : type.Name); return; } var typeDef = type.GetGenericTypeDefinition(); var typeName = useFullName ? typeDef.FullName : typeDef.Name; sb.Append(typeName); sb.Length -= typeName.Length - typeName.LastIndexOf('`'); sb.Append('<'); foreach (var typeArgument in type.GenericTypeArguments) { GetNiceGenericName(sb, typeArgument, useFullName); sb.Append(", "); } sb.Length -= 2; sb.Append('>'); } } 

Eh bien, c’est parce que le nom du type dans .NET est en fait IS List’1. Le “‘1” est ce qu’on appelle l’arité du générique, et il vous indique le nombre de parameters de type.

Cela est nécessaire pour pouvoir créer plus d’un type générique avec le même “nom” mais un nombre différent de parameters de type générique.

Par exemple, il existe plus d’un type “appelé” System.Action. Les vrais noms de ceux-ci sont System.Action’1, System.Action’2, System.Action’3 etc.

Donc, si vous savez que votre type est générique, vous pouvez supposer qu’il y a ce ‘XX à la fin du nom, vous pouvez donc couper cette partie, par exemple comme ceci:

 ssortingng strTypeName = typeof(List<>).Name.Substring(0, typeof(List<>).Name.LastIndexOf("`")); 

PS: S’il vous plaît remplacer “avec”.