Como obtenho o nome do tipo de um argumento de tipo genérico?

99

Se eu tiver uma assinatura de método como

public string myMethod<T>( ... )

Como posso, dentro do método, obter o nome do tipo que foi dado como argumento de tipo? Eu gostaria de fazer algo semelhante a typeof(T).FullName, mas isso realmente funciona ...

Tomas Aschan
fonte
10
typeof(T).FullName deve funcionar. O que está acontecendo em vez disso?
Nathan Taylor,
Recebi erros do compilador nessa instrução - mas aparentemente eles foram causados ​​por outra coisa, porque agora está funcionando. Obrigado!
Tomas Aschan,

Respostas:

156

Seu código deve funcionar. typeof(T).FullNameé perfeitamente válido. Este é um programa totalmente compilado e funcional:

using System;

class Program 
{
    public static string MyMethod<T>()
    {
        return typeof(T).FullName;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MyMethod<int>());

        Console.ReadKey();
    }

}

Executando as impressões acima (como esperado):

System.Int32
Reed Copsey
fonte
Certifique-se de testá-lo com MyMethod <int>> () e ver o que você obtém ... você deve levar em conta os tipos anuláveis ​​se você se preocupa com o tipo subjacente nesse cenário.
GR7
1
Você quer dizer " <int?>" Se sim, funciona, mas você obtém System.Nullable<int>(na sintaxe do nome completo), que é o que você esperaria ...
Reed Copsey,
Mesmo que eu já tivesse a solução (embora não tenha funcionado por algum motivo ...), vou dar-lhe os pontos de repetição por escrever a melhor resposta de longe =)
Tomas Aschan
1
Isso só me ajudou, pois eu assumi isso nameof(T)e typeof(T).Namefaria a mesma coisa. Acontece que nameof(T)apenas retorna T.
dahvyd
5

typeof(T).Namee typeof(T).FullNameestão trabalhando para mim. Recebo o tipo passado como um argumento.

GR7
fonte
1
ah. Se o tipo que você passou for anulável, para obter o tipo subjacente, você terá que usar algo como typeof (T) .GetGenericArguments () [0]
GR7
para verificar se o tipo é anulável, você usaria typeof (T) .IsGenericType e, se for, usaria o seguinte para obter o Nome ou FUllName ((Type) typeof (T) .GetGenericArguments () [0 ]). Nome
GR7
1

Supondo que você tenha alguma instância de um T disponível, não é diferente de qualquer outro tipo.

var t = new T();

var name = t.GetType().FullName;
womp
fonte
2
Você nem mesmo precisa de uma instância de T .... typeof (T) funciona bem sem nenhuma instância ... O seu terá um comportamento diferente se uma subclasse for passada para o método (como um argumento) ..
Reed Copsey
1
O problema com esse código é que se T não tiver um construtor sem parâmetros, ele não funcionará.
Nathan Taylor,
@Nathan - foi apenas um exemplo para mostrar a obtenção de uma instância de T. Presumivelmente em um método genérico ele terá algum tipo T disponível. @Reed - você está certo, é claro, presumi que era isso que ele queria.
womp
Outro problema seria no caso de T ser uma classe abstrata ou uma interface - o código acima não funcionaria. No caso de haver uma restrição de tipo genérico (o "onde"), esse tipo de código pode ser seguro, pois conhecemos o construtor e podemos realmente ter motivos para instanciar o tipo. Fora isso, a instanciação é um desperdício.
Andrew de