Ottieni il nome del tipo senza spazio dei nomi completo


293

Ho il codice seguente:

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

Ma

 typeof(T).ToString()

restituisce il nome completo incluso lo spazio dei nomi

Esiste un modo per ottenere solo il nome della classe (senza qualificatori di spazio dei nomi?)


7
Per inciso, la scrittura string1 + anything.ToString() + string2è ridondante. Il compilatore inserisce ToStringautomaticamente la chiamata in tal caso string1 + anything + string2.
Tim Robinson,

13
non sembrare duro ma, se avessi ispezionato quali proprietà sono disponibili Typetypeof(..)
sull'istanza

Risposte:


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

5
Namenon considera i parametri di tipo.
Gregregdennis,

73
Oppure this.GetType().Name, this.GetType().FullNameecc. Se si tratta di istanze.
avenmore,

1
Nameinoltre non considera i tipi nidificati!
Warlike Chimpanzee,

33

Prova questo per ottenere i parametri di tipo per tipi generici:

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

Forse non è la soluzione migliore (a causa della ricorsione), ma funziona. Le uscite sembrano:

Dictionary<String, Object>

3
Questa dovrebbe essere la risposta accettata in quanto prende correttamente in considerazione i tipi generici che possono ricorrere (ad esempio Dizionario <int?, Int?>).
Otis,

+1 per il concetto. Ma non mi piace l'ottimizzazione prematura fallita. Crea un nuovo StringBuilder in ogni chiamata ricorsiva (anche il caso base quando non viene utilizzato), ma ignora il string.Joinlambda temporaneo e LINQ. Basta usare Stringfino a quando non sai che è un collo di bottiglia. / rant
Nigel Touch

1
Nigel, dice proprio che probabilmente non è la soluzione migliore :)
gregsdennis,

ShortName è un nome più breve :)
Valera



5

Dopo C # 6.0 (incluso) puoi usare nameof expression:

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  

Nota! nameofnon ottiene il tipo di runtime dell'oggetto sottostante, è solo l'argomento compile-time. Se un metodo accetta un IEnumerable, nameof restituisce semplicemente "IEnumerable", mentre l'oggetto effettivo potrebbe essere "Elenco".


3
nameofnon restituisce il nome diType
Nigel Touch

@NigelTouch Ho controllato e nameofrestituito il nome dello Type, screenshot con prova: prntscr.com/irfk2c
Stas Boyarincev

1
Scusa, non ho spiegato bene. Ciò che intendo è che non ottiene il runtime dell'oggetto sottostante Type, è solo l'argomento compilazione-tempo. Se un metodo accetta un, IEnumerableallora nameofsemplicemente restituisce "IEnumerable", mentre l'oggetto reale potrebbe essere "List <string>". Non pensa che risponda alla domanda del PO.
Nigel Touch

-2

modo migliore di usare:

obj.GetType().BaseType.Name

1
Fornisci alcune spiegazioni alla tua risposta, per renderlo più chiaro per gli altri utenti.
Stanislav Mekhonoshin,

Una volta ho trovato "GetType (). Nome" scritto così in una funzione virtuale. Qualcuno può spiegarmi perché non ha obj.GetType (). BaseType.Name? Sto imparando. Capisco lo scopo ma non tutti i dettagli della sintassi. Grazie.
Diego Orellana,

Cosa c'entra il tipo di base con questo?
johnny 5

Il mio test obj.GetType().BaseType.Nameritorna "TypeInfo"che non è la soluzione desiderata come mi aspetto.
Nasenbaer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.