Wie erhalte ich den Typnamen eines generischen Typarguments?

98

Wenn ich eine Methodensignatur wie habe

public string myMethod<T>( ... )

Wie kann ich innerhalb der Methode den Namen des Typs abrufen, der als Typargument angegeben wurde? Ich würde gerne etwas Ähnliches machen typeof(T).FullName, aber das funktioniert tatsächlich ...

Tomas Aschan
quelle
10
typeof(T).FullName sollte funktionieren. Was passiert stattdessen?
Nathan Taylor
Ich habe Compilerfehler bei dieser Anweisung erhalten - aber anscheinend wurden sie durch etwas anderes verursacht, weil es jetzt funktioniert. Vielen Dank!
Tomas Aschan

Antworten:

155

Ihr Code sollte funktionieren. typeof(T).FullNameist vollkommen gültig. Dies ist ein vollständig kompiliertes, funktionierendes Programm:

using System;

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

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

        Console.ReadKey();
    }

}

Ausführen der obigen Ausdrucke (wie erwartet):

System.Int32
Reed Copsey
quelle
Stellen Sie sicher, dass Sie es mit MyMethod <int> >> () testen und sehen, was Sie erhalten ... Sie müssen nullfähige Typen berücksichtigen, wenn Sie den zugrunde liegenden Typ in diesem Szenario berücksichtigen.
GR7
1
Du meinst " <int?>" Wenn ja, funktioniert es, aber du bekommst System.Nullable<int>(in voller Namenssyntax), was du erwarten würdest ...
Reed Copsey
Obwohl ich bereits die Lösung hatte (obwohl es aus irgendeinem Grund nicht funktioniert hat ...), gebe ich Ihnen die Wiederholungspunkte für das Schreiben der mit Abstand besten Antwort =)
Tomas Aschan
1
Das hat mir nur geholfen, da ich davon ausgegangen bin nameof(T)und typeof(T).Namedasselbe tun würde. Es stellt sich heraus, nameof(T)gerade zurück T.
Dahvyd
5

typeof(T).Nameund typeof(T).FullNamearbeiten für mich. Ich bekomme den Typ als Argument übergeben.

GR7
quelle
1
Ah. Wenn der Typ, den Sie übergeben haben, Nullable ist, müssen Sie etwas wie typeof (T) .GetGenericArguments () [0]
GR7
Um zu überprüfen, ob der Typ nullwertfähig ist, verwenden Sie typeof (T) .IsGenericType. Wenn dies der Fall ist, verwenden Sie Folgendes, um den Namen oder FUllName ((Type) typeof (T) .GetGenericArguments () [0] abzurufen ]). Name
GR7
1

Angenommen, Sie haben eine Instanz eines T zur Verfügung, ist dies nicht anders als bei jedem anderen Typ.

var t = new T();

var name = t.GetType().FullName;
womp
quelle
2
Sie brauchen nicht einmal eine Instanz von T .... typeof (T) funktioniert gut ohne Instanz ... Ihre gibt ein anderes Verhalten, wenn eine Unterklasse an die Methode übergeben wird (als Argument) ..
Reed Copsey
1
Das Problem mit diesem Code ist, dass wenn T keinen parameterlosen Konstruktor hat, es nicht funktioniert.
Nathan Taylor
@ Nathan - es war nur ein Beispiel, um zu zeigen, wie man eine Instanz von T erhält. Vermutlich auf einer generischen Methode wird ihm ein T-Typ zur Verfügung stehen. @Reed - du hast natürlich Recht, ich nahm an, dass er danach suchte.
Womp
Ein weiteres Problem wäre der Fall, dass T eine abstrakte Klasse oder eine Schnittstelle ist - der obige Code würde nicht funktionieren. In dem Fall, dass es eine generische Typbeschränkung gibt (das "Wo"), kann dieser Codetyp sicher sein, da wir den Konstruktor kennen und möglicherweise Gründe haben, den Typ zu instanziieren. Davon abgesehen ist die Instanziierung verschwenderisch.
Andrew