¿Cómo obtengo el nombre de tipo de un argumento de tipo genérico?

99

Si tengo una firma de método como

public string myMethod<T>( ... )

¿Cómo puedo, dentro del método, obtener el nombre del tipo que se proporcionó como argumento de tipo? Me gustaría hacer algo similar a typeof(T).FullName, pero eso realmente funciona ...

Tomás Aschan
fuente
10
typeof(T).FullName debería funcionar. ¿Qué está pasando en su lugar?
Nathan Taylor
Recibí errores del compilador en esa declaración, pero aparentemente fueron causados ​​por otra cosa, porque ahora está funcionando. ¡Gracias!
Tomas Aschan

Respuestas:

156

Tu código debería funcionar. typeof(T).FullNamees perfectamente válido. Este es un programa completamente compilable y 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();
    }

}

Ejecutando las impresiones anteriores (como se esperaba):

System.Int32
Reed Copsey
fuente
Asegúrese de probarlo con MyMethod <int>> () y vea lo que obtiene ... debe tener en cuenta los tipos que aceptan valores NULL si se preocupa por el tipo subyacente en ese escenario.
GR7
1
Quieres decir " <int?>" Si es así, funciona, pero obtienes System.Nullable<int>(en la sintaxis del nombre completo), que es lo que esperarías ...
Reed Copsey
Aunque ya tenía la solución (aunque no funcionó por alguna razón ...), le daré los puntos de representante por escribir la mejor respuesta con diferencia =)
Tomas Aschan
1
Esto simplemente me ayudó, ya que asumí eso nameof(T)y typeof(T).Nameharía lo mismo. Resulta que nameof(T)solo vuelve T.
dahvyd
5

typeof(T).Namey typeof(T).FullNameestán trabajando para mí. Obtengo el tipo pasado como argumento.

GR7
fuente
1
ah. Si el tipo que pasó es Nullable, para obtener el tipo subyacente tendría que usar algo como typeof (T) .GetGenericArguments () [0]
GR7
para verificar si el tipo es anulable, usaría typeof (T) .IsGenericType, y si lo es, usaría lo siguiente para obtener el Nombre o FUllName ((Type) typeof (T) .GetGenericArguments () [0 ]). Nombre
GR7
1

Suponiendo que tenga alguna instancia de una T disponible, no es diferente a cualquier otro tipo.

var t = new T();

var name = t.GetType().FullName;
womp
fuente
2
Ni siquiera necesitas una instancia de T .... typeof (T) funciona bien sin instancia ... El tuyo dará un comportamiento diferente si se pasa una subclase al método (como argumento) ..
Reed Copsey
1
El problema con ese código es que si T no tiene un constructor sin parámetros, no funcionará.
Nathan Taylor
@Nathan: fue solo un ejemplo para mostrar cómo obtener una instancia de T. Presumiblemente, en un método genérico, tendrá algún tipo de T disponible. @Reed: tienes razón, por supuesto, asumí que eso era lo que buscaba.
womp
Otro problema sería en el caso de que T sea una clase abstracta o una interfaz; el código anterior no funcionaría. En el caso de que exista una restricción de tipo genérico (el "dónde"), entonces este tipo de código puede ser seguro ya que conocemos al constructor y puede que tengamos razones para crear una instancia del tipo. Aparte de esa instanciación es un desperdicio.
Andrew