Obter nome do tipo sem espaço para nome completo

293

Eu tenho o seguinte código:

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

Mas

 typeof(T).ToString()

retorna o nome completo, incluindo o espaço para nome

Existe alguma maneira de obter apenas o nome da classe (sem qualificadores de espaço para nome?)

leora
fonte
7
Aliás, escrever string1 + anything.ToString() + string2é redundante. O compilador insere a chamada ToStringautomaticamente, se você o fizer string1 + anything + string2.
Tim Robinson
13
não soar duro, mas, tinha-lhe inspecionou as propriedades que estão disponíveis na Typeinstância (como retornado por typeof(..)) eu tenho certeza que você iria descobrir isso sozinho ...
Peter Lillevold

Respostas:

530
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name
Tim Robinson
fonte
5
Namenão considera parâmetros de tipo.
gregsdennis
73
Ou this.GetType().Name, this.GetType().FullNameetc., se estiver lidando com instâncias.
precisa
1
Nametambém não considera tipos aninhados!
Warim Chimpanzee
33

Tente isso para obter 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();
}

Talvez não seja a melhor solução (devido à recursão), mas funciona. As saídas são parecidas com:

Dictionary<String, Object>
gregsdennis
fonte
3
Essa deve ser a resposta aceita, pois leva em consideração os tipos genéricos que podem ser recursivos (Dictionary <int?, Int?> Por exemplo).
Otis
+1 para o conceito. Mas não gosto da otimização prematura com falha. Ele cria um novo StringBuilder em cada chamada recursiva (mesmo no caso base quando não é usado), mas ignora o string.Joinlambda temporário e o LINQ. Basta usar Stringaté saber que é um gargalo. / rant
Nigel Touch
1
Nigel, ele diz ali que de provavelmente não é a melhor solução :)
gregsdennis
ShortName é um nome mais curto :)
Valera
9

use ( Type Properties )

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

typeof (T) .Name;

Datoon
fonte
5

Após o C # 6.0 (incluindo), você pode usar o nome da expressão:

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! nameofPara obter o tipo de tempo de execução do objeto subjacente, é apenas o argumento em tempo de compilação. Se um método aceitar um IEnumerable, nameof simplesmente retornará "IEnumerable", enquanto o objeto real poderá ser "List".

Stas Boyarincev
fonte
3
nameofnão retorna o nome doType
Nigel Touch
@NigelTouch Eu verifiquei e retornei nameofo nome da Typecaptura de tela com a prova: prntscr.com/irfk2c
Stas Boyarincev
1
Desculpe, eu não expliquei bem. O que quero dizer é que ele não obtém o tempo de execução do objeto subjacente Type, é apenas o argumento em tempo de compilação. Se um método aceita um IEnumerable, nameofsimplesmente retorna "IEnumerable", enquanto o objeto real pode ser "List <string>". Não acha que responde à pergunta do OP.
Nigel Toque
-2

melhor maneira de usar:

obj.GetType().BaseType.Name
Hossein Ebrahimi
fonte
1
Forneça algumas explicações para sua resposta, para torná-la mais clara para outros usuários.
Stanislav Mekhonoshin
Certa vez, encontrei "GetType (). Name" escrito assim dentro de uma função virtual. Alguém pode me explicar por que não possui o obj.GetType (). BaseType.Name? Eu estou aprendendo. Entendo o objetivo, mas nem todos os detalhes da sintaxe. Obrigado.
Diego Orellana
O que o tipo de base tem a ver com isso?
johnny 5
Meu teste obj.GetType().BaseType.Nameretorna, "TypeInfo"que não é a solução desejada, como eu esperava.
Nasenbaer #