Jak uzyskać nazwę typu argumentu typu ogólnego?

101

Jeśli mam podpis metody, taki jak

public string myMethod<T>( ... )

Jak mogę, wewnątrz metody, uzyskać nazwę typu, który został podany jako argument typu? Chciałbym zrobić coś podobnego typeof(T).FullName, ale to faktycznie działa ...

Tomas Aschan
źródło
10
typeof(T).FullName powinno działać. Co się dzieje zamiast tego?
Nathan Taylor
Mam błędy kompilatora w tym oświadczeniu - ale najwyraźniej były one spowodowane czymś innym, ponieważ teraz działa. Dzięki!
Tomas Aschan,

Odpowiedzi:

163

Twój kod powinien działać. typeof(T).FullNamejest całkowicie poprawne. To jest w pełni kompilujący, działający program:

using System;

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

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

        Console.ReadKey();
    }

}

Uruchomienie powyższych wydruków (zgodnie z oczekiwaniami):

System.Int32
Reed Copsey
źródło
Upewnij się, że przetestowałeś to za pomocą MyMethod <int>> () i zobacz, co otrzymujesz ... musisz uwzględnić typy dopuszczające wartość null, jeśli zależy Ci na typie bazowym w tym scenariuszu.
GR7
1
Masz na myśli " <int?>" Jeśli tak, to działa, ale otrzymujesz System.Nullable<int>(w składni pełnej nazwy), czego można się spodziewać ...
Reed Copsey
Chociaż miałem już rozwiązanie (chociaż z jakiegoś powodu nie zadziałało ...), dam ci punkty rep za napisanie najlepszej odpowiedzi zdecydowanie =)
Tomas Aschan
1
To po prostu pomogło mi, ponieważ założyłem to nameof(T)i typeof(T).Namezrobię to samo. Okazuje się, że nameof(T)po prostu wraca T.
dahvyd
7

typeof(T).Namei typeof(T).FullNamepracują dla mnie. Otrzymuję typ przekazany jako argument.

GR7
źródło
1
ah. Jeśli przekazany typ to Nullable, aby uzyskać typ bazowy, musiałbyś użyć czegoś takiego jak typeof (T). GetGenericArguments () [0]
GR7
aby sprawdzić, czy typ ma wartość nullable, użyłbyś typeof (T) .IsGenericType, a jeśli tak, użyłbyś poniższego, aby uzyskać Name lub FUllName ((Type) typeof (T). ])
.Nazwa
1

Zakładając, że masz dostępną instancję T, nie różni się ona od innych typów.

var t = new T();

var name = t.GetType().FullName;
womp
źródło
2
Nie potrzebujesz nawet instancji T .... typeof (T) działa dobrze bez instancji ... Twoje zachowanie będzie inne, jeśli podklasa zostanie przekazana do metody (jako argument) ..
Reed Copsey
1
Problem z tym kodem polega na tym, że jeśli T nie ma konstruktora bez parametrów, to nie zadziała.
Nathan Taylor
@Nathan - to był tylko przykład pokazujący uzyskanie instancji T. Przypuszczalnie przy metodzie ogólnej będzie miał do dyspozycji jakiś typ T. @Reed - oczywiście masz rację, założyłem, że o to mu chodziło.
womp
Inną kwestią byłaby sytuacja, w której T jest klasą abstrakcyjną lub interfejsem - powyższy kod by nie działał. W przypadku, gdy istnieje ograniczenie typu ogólnego („gdzie”), ten typ kodu może być bezpieczny, ponieważ znamy konstruktora i możemy faktycznie mieć powody do utworzenia wystąpienia typu. Poza tym tworzenie egzemplarzy jest marnotrawstwem.
Andrew,