Obtener el nombre del tipo sin espacio de nombres completo


293

Tengo el siguiente código:

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

Pero

 typeof(T).ToString()

devuelve el nombre completo, incluido el espacio de nombres

¿Hay alguna forma de obtener el nombre de la clase (sin ningún calificador de espacio de nombres?)


77
Por cierto, la escritura string1 + anything.ToString() + string2es redundante. El compilador inserta la llamada ToStringautomáticamente si lo hace string1 + anything + string2.
Tim Robinson el

13
no suena duro, pero, si hubieras inspeccionado qué propiedades están disponibles en la Typeinstancia (según lo devuelto typeof(..)), estoy bastante seguro de que lo descubrirías tú mismo ...
Peter Lillevold

Respuestas:


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

55
Nameno considera los parámetros de tipo.
gregsdennis

73
O this.GetType().Name, this.GetType().FullNameetc. si se trata de instancias.
avenmore

1
Name¡tampoco considera los tipos anidados!
Warlike Chimpanzee

33

Pruebe esto para obtener parámetros de tipo para tipos genéricos:

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

Quizás no sea la mejor solución (debido a la recurrencia), pero funciona. Las salidas se ven así:

Dictionary<String, Object>

3
Esta debería ser la respuesta aceptada, ya que tiene debidamente en cuenta los tipos genéricos que pueden repetirse (Diccionario <int?, Int?> Por ejemplo).
Otis

+1 para el concepto. Pero no me gusta la optimización prematura fallida. Crea una nueva StringBuilder en cada llamada recursiva (incluso el caso base cuando no se usa), pero ignora el string.Joinlambda temporal y LINQ. Solo use Stringhasta que sepa que es un cuello de botella. / rant
Nigel Touch

1
Nigel, dice que esa no es la mejor solución :)
gregsdennis

ShortName es un nombre más corto :)
Valera



5

Después del C # 6.0 (incluido) puede usar el nombre de expresión:

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! nameofno obtiene el tipo de tiempo de ejecución del objeto subyacente, es solo el argumento en tiempo de compilación. Si un método acepta un IEnumerable, nameof simplemente devuelve "IEnumerable", mientras que el objeto real podría ser "List".


3
nameofno devuelve el nombre de laType
Nigel Touch

@NigelTouch He comprobado y nameofdevuelto el nombre de la Typecaptura de pantalla con la prueba: prntscr.com/irfk2c
Stas Boyarincev

1
Lo siento, no te expliqué bien. Lo que quiero decir es que no obtiene el tiempo de ejecución del objeto subyacente Type, es solo el argumento en tiempo de compilación. Si un método acepta un IEnumerable, nameofsimplemente devuelve "IEnumerable", mientras que el objeto real podría ser "List <string>". No creo que responda la pregunta del OP.
Nigel Touch

-2

mejor forma de usar:

obj.GetType().BaseType.Name

1
Proporcione alguna explicación a su respuesta, para que sea más clara para otros usuarios.
Stanislav Mekhonoshin

Una vez encontré "GetType (). Name" simplemente escrito así dentro de una función virtual. ¿Alguien puede explicarme por qué no tiene el obj.GetType (). BaseType.Name? Estoy aprendiendo. Entiendo el propósito pero no todos los detalles de sintaxis. Gracias.
Diego Orellana

¿Qué tiene que ver el tipo base con esto?
Johnny 5

Mi prueba obj.GetType().BaseType.Nameregresa, "TypeInfo"que no es la solución deseada como espero.
Nasenbaer
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.