Obtenir le nom du type sans espace de noms complet


293

J'ai le code suivant:

return "[Inserted new " + typeof(T).ToString() + "]";

Mais

 typeof(T).ToString()

renvoie le nom complet, y compris l'espace de noms

Existe-t-il de toute façon juste pour obtenir le nom de classe (sans aucun qualificatif d'espace de noms?)


7
Soit dit en passant, l'écriture string1 + anything.ToString() + string2est redondante. ToStringSi vous le faites, le compilateur insère l'appel à automatiquement string1 + anything + string2.
Tim Robinson

13
pour ne pas paraître sévère, mais si vous aviez inspecté les propriétés disponibles sur l' Typeinstance (telles que retournées par typeof(..)), je suis sûr que vous le découvririez vous-même ...
Peter Lillevold

Réponses:


530
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

5
Namene prend pas en compte les paramètres de type.
gregsdennis

73
Ou this.GetType().Name, this.GetType().FullNameetc. s'il s'agit d'instances.
avenmore

1
Namene prend pas non plus en compte les types imbriqués!
Warlike Chimpanzee

33

Essayez ceci pour obtenir les paramètres de type pour les types génériques:

public static string CSharpName(this Type type)
{
    var sb = new StringBuilder();
    var name = type.Name;
    if (!type.IsGenericType) return name;
    sb.Append(name.Substring(0, name.IndexOf('`')));
    sb.Append("<");
    sb.Append(string.Join(", ", type.GetGenericArguments()
                                    .Select(t => t.CSharpName())));
    sb.Append(">");
    return sb.ToString();
}

Ce n'est peut-être pas la meilleure solution (en raison de la récursivité), mais cela fonctionne. Les sorties ressemblent à:

Dictionary<String, Object>

3
Cela devrait être la réponse acceptée car elle prend correctement en considération les types génériques qui peuvent récurrentes (Dictionary <int?, Int?> Par exemple).
Otis

+1 pour le concept. Mais n'aime pas l'optimisation prématurée échouée. Il crée un nouveau StringBuilder dans chaque appel récursif (même le cas de base lorsqu'il n'est pas utilisé), mais ignore les string.Joinlambda temporaires et LINQ. Utilisez-le Stringjusqu'à ce que vous sachiez qu'il s'agit d'un goulot d'étranglement. / rant
Nigel Touch

1
Nigel, il est dit que ce n'est probablement pas la meilleure solution :)
gregsdennis

ShortName est un nom plus court :)
Valera



5

Après le C # 6.0 (y compris), vous pouvez utiliser l' expression nameof :

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> f  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error This expression does not have a name  

Remarque! nameofne récupère pas le type d'exécution de l'objet sous-jacent, il s'agit simplement de l'argument de compilation. Si une méthode accepte un IEnumerable, nameof renvoie simplement "IEnumerable", alors que l'objet réel pourrait être "List".


3
nameofne renvoie pas le nom duType
Nigel Touch

@NigelTouch J'ai vérifié et nameofrenvoyé le nom du Type, capture d'écran avec preuve: prntscr.com/irfk2c
Stas Boyarincev

1
Désolé, je n'ai pas bien expliqué. Ce que je veux dire, c'est qu'il n'obtient pas le runtime de l'objet sous-jacent Type, c'est juste l'argument de compilation. Si une méthode accepte un, IEnumerableelle nameofrenvoie simplement "IEnumerable", alors que l'objet réel peut être "List <string>". Il ne pense pas que cela réponde à la question du PO.
Nigel Touch

-2

meilleure façon d'utiliser:

obj.GetType().BaseType.Name

1
Veuillez fournir des explications à votre réponse, pour la rendre plus claire pour les autres utilisateurs.
Stanislav Mekhonoshin

J'ai trouvé une fois "GetType (). Name" juste écrit comme ça dans une fonction virtuelle. Quelqu'un peut-il m'expliquer pourquoi il n'a pas l'obj.GetType (). BaseType.Name? J'apprends. Je comprends le but mais pas tous les détails de la syntaxe. Je vous remercie.
Diego Orellana

Qu'est-ce que le type de base a à voir avec cela?
johnny 5

Mon test obj.GetType().BaseType.Namerevient, "TypeInfo"ce qui n'est pas la solution recherchée comme je l'attends.
Nasenbaer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.