Typnamen ohne vollständigen Namespace abrufen


293

Ich habe folgenden Code:

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

Aber

 typeof(T).ToString()

Gibt den vollständigen Namen einschließlich des Namespace zurück

Gibt es sowieso nur den Klassennamen (ohne Namespace-Qualifikatoren?)


7
Das Schreiben string1 + anything.ToString() + string2ist übrigens überflüssig. Der Compiler fügt den Aufruf ToStringautomatisch ein, wenn Sie dies tun string1 + anything + string2.
Tim Robinson

13
Typetypeof(..)
Um

Antworten:


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

5
Nameberücksichtigt keine Typparameter.
Gregsdennis

73
Oder this.GetType().Name, this.GetType().FullNameetc. , wenn sie mit Fällen zu tun.
Avenmore

1
Nameberücksichtigt auch keine verschachtelten Typen!
Kriegsähnlicher Schimpanse

33

Versuchen Sie dies, um Typparameter für generische Typen abzurufen:

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();
}

Vielleicht nicht die beste Lösung (aufgrund der Rekursion), aber es funktioniert. Die Ausgaben sehen wie folgt aus:

Dictionary<String, Object>

3
Dies sollte die akzeptierte Antwort sein, da generische Typen, die möglicherweise wiederkehren, richtig berücksichtigt werden (z. B. Dictionary <int ?, Int?>).
Otis

+1 für das Konzept. Aber ich mag die fehlgeschlagene vorzeitige Optimierung nicht. Bei jedem rekursiven Aufruf wird ein neuer erstellt StringBuilder(auch der Basisfall, wenn er nicht verwendet wird), das string.Jointemporäre und das LINQ-Lambda werden jedoch ignoriert . Verwenden StringSie es einfach, bis Sie wissen, dass es sich um einen Engpass handelt. / rant
Nigel Touch

1
Nigel, es heißt genau dort, das ist wahrscheinlich nicht die beste Lösung :)
Gregsdennis

Kurzname ist ein kürzerer Name :)
Valera



5

Nach C # 6.0 (einschließlich) können Sie den Namen des Ausdrucks verwenden:

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  

Hinweis! nameofDer Laufzeittyp des zugrunde liegenden Objekts wird nicht abgerufen, sondern nur das Argument zur Kompilierungszeit. Wenn eine Methode eine IEnumerable akzeptiert, gibt nameof einfach "IEnumerable" zurück, während das eigentliche Objekt "List" sein könnte.


3
nameofgibt nicht den Namen desType
Nigel Touch

@NigelTouch Ich habe nameofden Namen des TypeScreenshots mit Beweis überprüft und zurückgegeben : prntscr.com/irfk2c
Stas Boyarincev

1
Entschuldigung, ich habe es nicht gut erklärt. Was ich damit meine ist, dass es nicht die Laufzeit des zugrunde liegenden Objekts erhält Type, sondern nur das Argument zur Kompilierungszeit. Wenn eine Methode ein akzeptiert, IEnumerablewird nameofeinfach "IEnumerable" zurückgegeben, während das eigentliche Objekt "List <string>" sein könnte. Es glaubt nicht, dass es die Frage des OP beantwortet.
Nigel Touch

-2

beste Verwendung:

obj.GetType().BaseType.Name

1
Bitte erläutern Sie Ihre Antwort, um sie anderen Benutzern klarer zu machen.
Stanislav Mekhonoshin

Ich habe einmal "GetType (). Name" gefunden, das so in einer virtuellen Funktion geschrieben wurde. Kann mir jemand erklären, warum es nicht den obj.GetType (). BaseType.Name hat? Ich lerne. Ich verstehe den Zweck, aber nicht alle Syntaxdetails. Danke dir.
Diego Orellana

Was hat der Basistyp damit zu tun?
Johnny 5

Mein Test obj.GetType().BaseType.Namekehrt zurück, "TypeInfo"was nicht die gewünschte Lösung ist, wie ich es erwarte.
Nasenbaer
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.