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?

6voto

Dan Malcolm Punkte 4312

Sie können den Typ von "T" von jedem Auflistungstyp, der IEnumerable<T> implementiert, wie folgt erhalten:

public static Type GetCollectionItemType(Type collectionType)
{
    var types = collectionType.GetInterfaces()
        .Where(x => x.IsGenericType 
            && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        .ToArray();
    // Only support collections that implement IEnumerable<T> once.
    return types.Length == 1 ? types[0].GetGenericArguments()[0] : null;
}

Beachten Sie, dass es keine Sammlungstypen unterstützt, die IEnumerable<T> zweimal implementieren, z. B.

public class WierdCustomType : IEnumerable<int>, IEnumerable<string> { ... }

Ich nehme an, Sie könnten ein Array von Typen zurückgeben, wenn Sie dies unterstützen müssen...

Außerdem können Sie das Ergebnis pro Auflistungstyp zwischenspeichern, wenn Sie dies häufig tun (z. B. in einer Schleife).

1voto

Fantastory Punkte 1814

Verwendung von Die Lösung von 3dGrabber :

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

//and now

var list = new Dictionary<string, int>();
var stronglyTypedVar = list.GetEnumeratedType();

0voto

Karanvir Kang Punkte 2029
public bool IsCollection<T>(T value){
  var valueType = value.GetType();
  return valueType.IsArray() || typeof(IEnumerable<object>).IsAssignableFrom(valueType) || typeof(IEnumerable<T>).IsAssignableFrom(valuetype);
}

1 Stimmen

Dies scheint die Frage zu klären, ob der Typ eine Art Liste ist, aber die Frage ist eher, wie man feststellen kann, mit welchem generischen Typparameter ein Typ, von dem bekannt ist, dass er eine Liste ist, bereits initialisiert wurde.

0 Stimmen

Eine Erklärung wäre angebracht. Z.B.: Was ist der Kern der Sache? Was ist die Idee? Bitte antworten Sie bis Bearbeitung Ihrer Antwort , nicht hier in den Kommentaren ( ohne "Bearbeiten:", "Aktualisieren:" oder ähnlich - die Antwort sollte so aussehen, als wäre sie heute geschrieben worden).

0voto

Fatih Çelik Punkte 381

Wenn Sie den zugrundeliegenden Typ einer Eigenschaft wissen wollen, versuchen Sie dies:

propInfo.PropertyType.UnderlyingSystemType.GenericTypeArguments[0]

-1voto

Alen.Toma Punkte 4903

So habe ich es gemacht:

internal static Type GetElementType(this Type type)
{
    // Use type.GenericTypeArguments if it exists
    if (type.GenericTypeArguments.Any())
        return type.GenericTypeArguments.First();

    return type.GetRuntimeProperty("Item").PropertyType);
}

Dann nennen Sie es so:

var item = Activator.CreateInstance(iListType.GetElementType());

Oder

var item = Activator.CreateInstance(Bar.GetType().GetElementType());

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