Comment obtenir le nom de type d'un argument de type générique?

99

Si j'ai une signature de méthode comme

public string myMethod<T>( ... )

Comment puis-je, à l'intérieur de la méthode, obtenir le nom du type qui a été donné comme argument de type? J'aimerais faire quelque chose de similaire à typeof(T).FullName, mais cela fonctionne réellement ...

Tomas Aschan
la source
10
typeof(T).FullName devrait fonctionner. Que se passe-t-il à la place?
Nathan Taylor
J'ai eu des erreurs de compilation sur cette déclaration - mais apparemment, elles ont été causées par autre chose, car maintenant cela fonctionne. Merci!
Tomas Aschan

Réponses:

156

Votre code devrait fonctionner. typeof(T).FullNameest parfaitement valable. Il s'agit d'un programme entièrement compilé et fonctionnel:

using System;

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

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

        Console.ReadKey();
    }

}

Exécution des impressions ci-dessus (comme prévu):

System.Int32
Reed Copsey
la source
Assurez-vous de le tester avec MyMethod <int>> () et voyez ce que vous obtenez ... vous devez tenir compte des types Nullable si vous vous souciez du type sous-jacent dans ce scénario.
GR7
1
Vous voulez dire " <int?>" Si oui, cela fonctionne, mais vous obtenez System.Nullable<int>(dans la syntaxe du nom complet), ce à quoi vous vous attendez ...
Reed Copsey
Même si j'avais déjà la solution (même si cela n'a pas fonctionné pour une raison quelconque ...), je vais vous donner les points de répétition pour avoir écrit la meilleure réponse de loin =)
Tomas Aschan
1
Cela m'a juste aidé puisque je l'ai supposé nameof(T)et que typeof(T).Nameje ferais la même chose. Il s'avère nameof(T)que les retours T.
dahvyd le
5

typeof(T).Nameet typeof(T).FullNametravaillent pour moi. Je reçois le type passé en argument.

GR7
la source
1
ah. Si le type que vous avez passé est Nullable, pour obtenir le type sous-jacent, vous devez utiliser quelque chose comme typeof (T) .GetGenericArguments () [0]
GR7
pour vérifier si le type est nullable, vous utiliseriez typeof (T) .IsGenericType, et si c'est le cas, vous utiliseriez ce qui suit pour obtenir le nom ou le FUllName ((Type) typeof (T) .GetGenericArguments () [0 ]). Nom
GR7
1

En supposant que vous ayez une instance d'un T disponible, ce n'est pas différent de tout autre type.

var t = new T();

var name = t.GetType().FullName;
womp
la source
2
Vous n'avez même pas besoin d'une instance de T .... typeof (T) fonctionne bien sans instance ... Le vôtre donnera un comportement différent si une sous-classe est passée dans la méthode (en argument) ..
Reed Copsey
1
Le problème avec ce code est que si T n'a pas de constructeur sans paramètre, il ne fonctionnera pas.
Nathan Taylor
@Nathan - c'était juste un exemple pour montrer l'obtention d'une instance de T.Vraisemblablement sur une méthode générique, il aura un type de T disponible. @Reed - vous avez raison bien sûr, j'ai supposé que c'était ce qu'il cherchait.
womp
Un autre problème serait dans le cas où T est une classe abstraite ou une interface - le code ci-dessus ne fonctionnerait pas. Dans le cas où il y a une contrainte de type générique (le «où»), alors ce type de code peut être sûr puisque nous connaissons le constructeur et pouvons en fait avoir des raisons d'instancier le type. Autre que cette instanciation est un gaspillage.
Andrew