860 Stimmen

Wie erhält man den Typ von T von einem Mitglied einer generischen Klasse oder Methode?

Nehmen wir an, ich habe ein generisches Mitglied in einer Klasse oder Methode, etwa so:

public class Foo<T>
{
    public List<T> Bar { get; set; }

    public void Baz()
    {
        // get type of T
    }   
}

Wenn ich die Klasse instanziere, wird die T wird MyTypeObject1 Die Klasse hat also eine generische Listeneigenschaft: List<MyTypeObject1> . Dasselbe gilt für eine generische Methode in einer nicht-generischen Klasse:

public class Foo
{
    public void Bar<T>()
    {
        var baz = new List<T>();

        // get type of T
    }
}

Ich würde gerne wissen, welche Art von Objekten die Liste meiner Klasse enthält. Also welche Art von T wird die Listeneigenschaft namens Bar oder die lokale Variable baz enthalten?

Ich kann nicht tun Bar[0].GetType() , da die Liste auch Nullelemente enthalten kann. Wie kann ich das tun?

897voto

Tamas Czinege Punkte 114595

Wenn ich es richtig verstehe, hat Ihre Liste den gleichen Typ-Parameter wie die Container-Klasse selbst. Wenn dies der Fall ist, dann:

Type typeParameterType = typeof(T);

Wenn Sie in der glücklichen Lage sind, über object als Typparameter, siehe Marcs Antwort .

69 Stimmen

Ich liebe es, wie lesbar typeof ist. Wenn Sie den Typ von T wissen wollen, verwenden Sie einfach typeof(T) :)

2 Stimmen

Ich habe einfach typeof(Type) verwendet und es funktioniert wunderbar.

3 Stimmen

Sie können typeof() jedoch nicht mit einem generischen Parameter verwenden.

591voto

Marc Gravell Punkte 970173

(Anmerkung: Ich gehe davon aus, dass Sie nur Folgendes wissen object o IList o.ä., und dass die Liste zur Laufzeit von beliebigem Typ sein kann)

Wenn Sie wissen, dass es sich um eine List<T> , dann:

Type type = abc.GetType().GetGenericArguments()[0];

Eine andere Möglichkeit ist, sich den Indexer anzusehen:

Type type = abc.GetType().GetProperty("Item").PropertyType;

Verwendung der neuen TypeInfo:

using System.Reflection;
// ...
var type = abc.GetType().GetTypeInfo().GenericTypeArguments[0];

3 Stimmen

Type type = abc.GetType().GetGenericArguments()[0]; ==> Array-Index außerhalb der Grenzen...

34 Stimmen

@Daok : dann ist es keine List<T>

0 Stimmen

Brauchen Sie etwas für BindingList oder List oder was auch immer Objekt, das eine <T> halten. Was ich tue, verwenden Sie eine benutzerdefinierte BindingListView<T>

65voto

3dGrabber Punkte 4250

Mit der folgenden Erweiterungsmethode können Sie auf die Reflexion verzichten:

public static Type GetListType<T>(this List<T> _)
{
    return typeof(T);
}

Oder allgemeiner ausgedrückt:

public static Type GetEnumeratedType<T>(this IEnumerable<T> _)
{
    return typeof(T);
}

Uso:

List<string>        list    = new List<string> { "a", "b", "c" };
IEnumerable<string> strings = list;
IEnumerable<object> objects = list;

Type listType    = list.GetListType();           // string
Type stringsType = strings.GetEnumeratedType();  // string
Type objectsType = objects.GetEnumeratedType();  // BEWARE: object

16 Stimmen

Dies ist nur dann sinnvoll, wenn Sie bereits wissen, um welche Art von T zur Kompilierzeit. In diesem Fall brauchen Sie eigentlich überhaupt keinen Code.

2 Stimmen

@recursive: Es ist nützlich, wenn Sie mit einer Liste eines anonymen Typs arbeiten.

34voto

Rauhotz Punkte 7594

Versuchen Sie

list.GetType().GetGenericArguments()

7 Stimmen

New List<int>().GetType().GetGenericArguments() liefert hier System.Type[1] mit System.Int32 als Eintrag

1 Stimmen

@Rauhotz der GetGenericArguments Methode gibt ein Array-Objekt von Type , aus dem Sie dann die Position des benötigten generischen Typs auslesen müssen. Wie zum Beispiel Type<TKey, TValue> : Sie müssen GetGenericArguments()[0] zu erhalten TKey Typ und GetGenericArguments()[1] zu erhalten TValue Typ

29voto

Sebi Punkte 3694

Wenn Sie nicht die gesamte Type-Variable benötigen und nur den Typ überprüfen wollen, können Sie einfach eine temporäre Variable erstellen und die is Betreiber.

T checkType = default(T);

if (checkType is MyClass)
{}

0 Stimmen

Dies sollte die akzeptierte Antwort sein, die mit Sicherheit am leistungsfähigsten ist.

0 Stimmen

Programmieren wie ein Profi :)

0 Stimmen

@EbrahimKarimi Auf jeden Fall :-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X