¿hay una manera de recuperar el tipo T
de 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
IEnumerable
por 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.GetGenericArguments
en 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 type
parámetro en lugar de unobject obj
parámetro: no puede simplemente reemplazarobj.GetType()
contype
porque si pasa,typeof(IEnumerable<T>)
no obtiene nada. Para solucionar esto, pruebe eltype
propio 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 unaT
nota enGenericTypeArguments
lugar 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
IActionResult
fuente
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
IEnumerable
en cuenta lo no genérico ,object
en este caso devuelve , porque toma unaType
instancia en lugar de una concreta como argumento. Por cierto, ya que x representa lo desconocido , este video me pareció interesante, aunque irrelevante.fuente