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?)

Leora
quelle
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
Tim Robinson
quelle
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>
gregsdennis
quelle
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
9

Nutzen Sie ( Type Properties )

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;
Pranay Rana
quelle
5

typeof (T) .Name;

Datoon
quelle
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.

Stas Boyarincev
quelle
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
Hossein Ebrahimi
quelle
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