Come ottengo il nome del tipo di un argomento di tipo generico?


99

Se ho una firma del metodo come

public string myMethod<T>( ... )

Come posso, all'interno del metodo, ottenere il nome del tipo che è stato dato come argomento del tipo? Mi piacerebbe fare qualcosa di simile a typeof(T).FullName, ma funziona davvero ...


10
typeof(T).FullName dovrebbe funzionare. Cosa sta succedendo invece?
Nathan Taylor

Ho ricevuto errori del compilatore su quella dichiarazione, ma a quanto pare sono stati causati da qualcos'altro, perché ora funziona. Grazie!
Tomas Aschan

Risposte:


156

Il tuo codice dovrebbe funzionare. typeof(T).FullNameè perfettamente valido. Questo è un programma completamente compilabile e funzionante:

using System;

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

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

        Console.ReadKey();
    }

}

Esecuzione delle stampe precedenti (come previsto):

System.Int32

Assicurati di testarlo con MyMethod <int>> () e vedi cosa ottieni ... devi tenere conto dei tipi nullable se ti interessa il tipo sottostante in quello scenario.
GR7

1
Vuoi dire " <int?>" Se è così, funziona, ma ottieni System.Nullable<int>(nella sintassi del nome completo), che è quello che ti aspetteresti ...
Reed Copsey

Anche se avevo già la soluzione (anche se non ha funzionato per qualche motivo ...), ti darò i punti rep per aver scritto di gran lunga la risposta migliore =)
Tomas Aschan

1
Questo mi ha solo aiutato poiché lo pensavo nameof(T)e typeof(T).Nameavrei fatto la stessa cosa. Risulta nameof(T)solo ritorni T.
dahvyd

5

typeof(T).Namee typeof(T).FullNamestanno lavorando per me. Ottengo il tipo passato come argomento.


1
ah. Se il tipo che hai passato è Nullable, per ottenere il tipo sottostante dovresti usare qualcosa come typeof (T) .GetGenericArguments () [0]
GR7

per verificare se il tipo è nullable, dovresti usare typeof (T) .IsGenericType e, in tal caso, dovresti usare quanto segue per ottenere il Name o FUllName ((Type) typeof (T) .GetGenericArguments () [0 ]) Nome
GR7

1

Supponendo che tu abbia qualche istanza di T disponibile, non è diverso da qualsiasi altro tipo.

var t = new T();

var name = t.GetType().FullName;

2
Non hai nemmeno bisogno di un'istanza di T .... typeof (T) funziona bene senza istanze ... Il tuo darà un comportamento diverso se una sottoclasse viene passata nel metodo (come argomento) ..
Reed Copsey

1
Il problema con quel codice è che se T non ha un costruttore senza parametri, non funzionerà.
Nathan Taylor

@ Nathan - era solo un esempio per mostrare come ottenere un'istanza di T. Presumibilmente su un metodo generico avrà un tipo di T disponibile. @Reed - hai ragione ovviamente, pensavo fosse quello che stava cercando.
womp

Un altro problema sarebbe nel caso in cui T sia una classe astratta o un'interfaccia: il codice sopra non funzionerebbe. Nel caso in cui esista un vincolo di tipo generico (il "dove"), questo tipo di codice può essere sicuro poiché conosciamo il costruttore e potremmo effettivamente avere motivi per istanziare il tipo. Diverso da quello l'istanza è uno spreco.
Andrew
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.