160 votes

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

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 type ? J'aimerais faire quelque chose de similaire à typeof(T).FullName, mais ça marche vraiment...

248voto

Reed Copsey Points 315315

Votre code devrait fonctionner. typeof(T).FullName est parfaitement valide. Il s'agit d'un programme entièrement compilable 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 tirages ci-dessus (comme prévu) :

System.Int32

18voto

Paul Smith Points 1064

Cette méthode d'extension produit le nom de type simple pour les types non génériques et ajoute la liste des arguments génériques pour les types génériques. Cela fonctionne très bien pour les scénarios où vous n'avez pas besoin de vous soucier des arguments génériques internes, comme IDictionary<int, IDictionary<int, string>>.

using System;
using System.Linq;

namespace Extensions
{ 
    public static class TypeExtensions
    {
        /// <summary>
        /// Returns the type name. If this is a generic type, appends
        /// the list of generic type arguments between angle brackets.
        /// (Does not account for embedded / inner generic arguments.)
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>System.String.</returns>
        public static string GetFormattedName(this Type type)
        {
            if(type.IsGenericType)
            {
                string genericArguments = type.GetGenericArguments()
                                    .Select(x => x.Name)
                                    .Aggregate((x1, x2) => $"{x1}, {x2}");
                return $"{type.Name.Substring(0, type.Name.IndexOf("`"))}"
                     + $"<{genericArguments}>";
            }
            return type.Name;
        }
    }
}

15voto

GR7 Points 1330

typeof(T).Name et typeof(T).FullName travaillent pour moi. Je reçois le type passé comme argument.

4voto

Jim Aho Points 66

Votre code devrait fonctionner. Vous pouvez également obtenir le nom de la classe au lieu du nom complet, y compris l'espace de noms, par exemple :

using System;

namespace ConsoleApp1
{
    class Program
    {
        public static string GettingName<T>() => typeof(T).Name;

        public static string GettingFullName<T>() => typeof(T).FullName;

        static void Main(string[] args)
        {
            Console.WriteLine($"Name: {GettingName<decimal>()}");
            Console.WriteLine($"FullName: {GettingFullName<decimal>()}");
        }
    }
}

La sortie de l'exécution du programme ci-dessus est :

Name: Decimal
FullName: System.Decimal

Voici un violon en filet du code ci-dessus que vous pouvez essayer

2voto

womp Points 71924

En supposant que vous avez 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;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X