gibt es eine Möglichkeit Art abzurufen T
aus IEnumerable<T>
durch Reflexion?
z.B
Ich habe eine variable IEnumerable<Child>
Info. Ich möchte den Typ des Kindes durch Reflexion abrufen
c#
generics
reflection
Usman Masood
quelle
quelle
Antworten:
Somit ist
druckt
System.String
.Siehe MSDN für
Type.GetGenericArguments
.Bearbeiten: Ich glaube, dies wird die Bedenken in den Kommentaren ansprechen:
Einige Objekte implementieren mehr als ein generisches Objekt,
IEnumerable
daher muss eine Aufzählung von ihnen zurückgegeben werden.Bearbeiten: Obwohl, ich muss sagen, es eine schreckliche Idee für eine Klasse ist,
IEnumerable<T>
für mehr als eine zu implementierenT
.quelle
Ich würde nur eine Erweiterungsmethode machen. Dies funktionierte mit allem, was ich darauf warf.
quelle
Ich hatte ein ähnliches Problem. Die ausgewählte Antwort funktioniert für tatsächliche Instanzen. In meinem Fall hatte ich nur einen Typ (von a
PropertyInfo
).Die ausgewählte Antwort schlägt fehl, wenn der Typ selbst
typeof(IEnumerable<T>)
keine Implementierung von istIEnumerable<T>
.In diesem Fall funktioniert Folgendes:
quelle
Type.GenericTypeArguments
- nur für dotNet FrameWork Version> = 4.5. Ansonsten -Type.GetGenericArguments
stattdessen verwenden.Wenn Sie das kennen
IEnumerable<T>
(über Generika), danntypeof(T)
sollte es einfach funktionieren. Andernfalls (fürobject
oder nicht generischIEnumerable
) überprüfen Sie die implementierten Schnittstellen:quelle
Type type
Parameter und nicht alsobject obj
Parameter: Sie können nicht nur ersetzenobj.GetType()
mit ,type
denn wenn man in gebentypeof(IEnumerable<T>)
Sie bekommen nichts. Um dies zu umgehen, testen Sie dastype
selbst, um festzustellen, ob es sich um ein Generikum vonIEnumerable<>
und dann um seine Schnittstellen handelt.Vielen Dank für die Diskussion. Ich habe es als Grundlage für die unten stehende Lösung verwendet, die für alle Fälle, die für mich von Interesse sind (IEnumerable, abgeleitete Klassen usw.), gut funktioniert. Ich dachte, ich sollte hier teilen, falls jemand es auch braucht:
quelle
someCollection.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()?.FirstOrDefault()
Benutz einfach
typeof(T)
BEARBEITEN : Oder verwenden Sie .GetType (). GetGenericParameter () für ein instanziiertes Objekt, wenn Sie kein T haben.
quelle
Eine Alternative für einfachere Situationen, in denen entweder eine
IEnumerable<T>
oder eineT
NotizGenericTypeArguments
anstelle von verwendet wirdGetGenericArguments()
.quelle
Dies ist eine Verbesserung der Lösung von Eli Algranti, da sie auch dort funktioniert, wo sich der
IEnumerable<>
Typ auf einer beliebigen Ebene im Vererbungsbaum befindet.Diese Lösung erhält den Elementtyp von jedem
Type
. Wenn der Typ kein istIEnumerable<>
, wird der übergebene Typ zurückgegeben. Verwenden Sie für ObjekteGetType
. Verwenden Sie für Typentypeof
diese Erweiterungsmethode und rufen Sie sie für das Ergebnis auf.quelle
Ich weiß, dass dies ein bisschen alt ist, aber ich glaube, dass diese Methode alle in den Kommentaren genannten Probleme und Herausforderungen abdecken wird. Dank an Eli Algranti für die Inspiration meiner Arbeit.
quelle
Dies ist eine rekursive Funktion, die zuerst die Liste der generischen Typen vertieft, bis eine konkrete Typdefinition ohne innere generische Typen erhalten wird.
Ich habe diese Methode mit folgendem Typ getestet:
ICollection<IEnumerable<ICollection<ICollection<IEnumerable<IList<ICollection<IEnumerable<IActionResult>>>>>>>>
was zurückkehren sollte
IActionResult
quelle
typeof(IEnumerable<Foo>)
. gibt das erste generische Argument zurück - in diesem Fall .GetGenericArguments()
[0]
typeof(Foo)
quelle
So mache ich es normalerweise (über die Erweiterungsmethode):
quelle
Hier ist meine unlesbare Version des Linq-Abfrageausdrucks.
Beachten Sie, dass die Methode auch nicht generische
IEnumerable
Elemente berücksichtigt.object
In diesem Fall wird sie zurückgegeben, da aType
als Argument eher eine als eine konkrete Instanz verwendet wird. Übrigens, da x das Unbekannte darstellt , fand ich dieses Video interessant, obwohl es irrelevant ist.quelle