¿hay una manera de recuperar el tipo Tde IEnumerable<T>medio de la reflexión?
p.ej
tengo una IEnumerable<Child>información variable ; quiero recuperar el tipo de niño a través de la reflexión
c#
generics
reflection
Usman Masood
fuente
fuente

Respuestas:
Por lo tanto,
impresiones
System.String.Consulte MSDN para
Type.GetGenericArguments.Editar: creo que esto abordará las preocupaciones en los comentarios:
Algunos objetos implementan más de un genérico
IEnumerablepor lo que es necesario devolver una enumeración de ellos.Editar: Aunque, debo decir, es una idea terrible que una clase implemente
IEnumerable<T>para más de unoT.fuente
Solo haría un método de extensión. Esto funcionó con todo lo que le lancé.
fuente
Tuve un problema similar. La respuesta seleccionada funciona para instancias reales. En mi caso solo tenía un tipo (de a
PropertyInfo).La respuesta seleccionada falla cuando el tipo en sí
typeof(IEnumerable<T>)no es una implementación deIEnumerable<T>.Para este caso funciona lo siguiente:
fuente
Type.GenericTypeArguments- solo para dotNet FrameWork versión> = 4.5. De lo contrario, utiliceType.GetGenericArgumentsen su lugar.Si conoce
IEnumerable<T>(a través de genéricos), entoncestypeof(T)debería funcionar. De lo contrario (paraobject, o el no genéricoIEnumerable), verifique las interfaces implementadas:fuente
Type typeparámetro en lugar de unobject objparámetro: no puede simplemente reemplazarobj.GetType()contypeporque si pasa,typeof(IEnumerable<T>)no obtiene nada. Para solucionar esto, pruebe eltypepropio para ver si es un genérico deIEnumerable<>y luego sus interfaces.Muchas gracias por la discusión. Lo usé como base para la solución a continuación, que funciona bien para todos los casos que me interesan (IEnumerable, clases derivadas, etc.). Pensé que debería compartir aquí en caso de que alguien lo necesite también:
fuente
someCollection.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()?.FirstOrDefault()Solo usa
typeof(T)EDITAR: O use .GetType (). GetGenericParameter () en un objeto instanciado si no tiene T.
fuente
Una alternativa para situaciones más simples en las que se utilizará una
IEnumerable<T>o unaTnota enGenericTypeArgumentslugar deGetGenericArguments().fuente
Esta es una mejora de la solución de Eli Algranti, ya que también funcionará cuando el
IEnumerable<>tipo esté en cualquier nivel del árbol de herencia.Esta solución obtendrá el tipo de elemento de any
Type. Si el tipo no es unIEnumerable<>, devolverá el tipo pasado. Para objetos, useGetType. Para tipos, usetypeof, luego llame a este método de extensión en el resultado.fuente
Sé que esto es un poco antiguo, pero creo que este método cubrirá todos los problemas y desafíos indicados en los comentarios. Gracias a Eli Algranti por inspirar mi trabajo.
fuente
Esta es una función recursiva que profundizará primero en la lista de tipos genéricos hasta que obtenga una definición de tipo concreta sin tipos genéricos internos.
Probé este método con este tipo:
ICollection<IEnumerable<ICollection<ICollection<IEnumerable<IList<ICollection<IEnumerable<IActionResult>>>>>>>>que debería volver
IActionResultfuente
typeof(IEnumerable<Foo>). devolverá el primer argumento genérico, en este caso .GetGenericArguments()[0]typeof(Foo)fuente
así es como suelo hacerlo (a través del método de extensión):
fuente
Aquí está mi versión ilegible de expresión de consulta Linq ...
Tenga en cuenta que el método también tiene
IEnumerableen cuenta lo no genérico ,objecten este caso devuelve , porque toma unaTypeinstancia en lugar de una concreta como argumento. Por cierto, ya que x representa lo desconocido , este video me pareció interesante, aunque irrelevante.fuente