existe uma maneira de recuperar o tipo T
por IEnumerable<T>
meio da reflexão?
por exemplo
eu tenho uma IEnumerable<Child>
informação variável ; eu quero recuperar o tipo de criança através da reflexão
c#
generics
reflection
Usman Masood
fonte
fonte
Respostas:
Assim,
impressões
System.String
.Consulte MSDN para
Type.GetGenericArguments
.Edit: Acredito que isso resolverá as preocupações nos comentários:
Alguns objetos implementam mais de um genérico,
IEnumerable
portanto, é necessário retornar uma enumeração deles.Edit: Embora, devo dizer, seja uma ideia terrível para uma classe implementar
IEnumerable<T>
para mais de umT
.fonte
Eu acabaria de fazer um método de extensão. Isso funcionou com tudo que eu joguei nele.
fonte
Eu tive um problema parecido. A resposta selecionada funciona para instâncias reais. No meu caso, tinha apenas um tipo (de a
PropertyInfo
).A resposta selecionada falha quando o próprio tipo
typeof(IEnumerable<T>)
não é uma implementação deIEnumerable<T>
.Para este caso, funciona o seguinte:
fonte
Type.GenericTypeArguments
- apenas para dotNet FrameWork version> = 4.5. Caso contrário - use em seuType.GetGenericArguments
lugar.Se você conhece o
IEnumerable<T>
(via genéricos), entãotypeof(T)
deve funcionar. Caso contrário (paraobject
, ou não genéricoIEnumerable
), verifique as interfaces implementadas:fonte
Type type
parâmetro em vez de umobject obj
parâmetro: você não pode simplesmente substituirobj.GetType()
portype
porque, se você passar,typeof(IEnumerable<T>)
não receberá nada. Para contornar isso, teste otype
próprio para ver se é um genérico deIEnumerable<>
e, em seguida, suas interfaces.Muito obrigado pela discussão. Usei-o como base para a solução abaixo, que funciona bem para todos os casos que me interessam (IEnumerable, classes derivadas, etc). Achei que deveria compartilhar aqui, caso alguém precise também:
fonte
someCollection.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()?.FirstOrDefault()
Apenas use
typeof(T)
EDIT: Ou use .GetType (). GetGenericParameter () em um objeto instanciado se você não tiver T.
fonte
Uma alternativa para situações mais simples em que será um
IEnumerable<T>
ouT
- observe o uso de emGenericTypeArguments
vez deGetGenericArguments()
.fonte
Esta é uma melhoria na solução de Eli Algranti, pois também funcionará onde o
IEnumerable<>
tipo está em qualquer nível na árvore de herança.Esta solução obterá o tipo de elemento de qualquer
Type
. Se o tipo não for umIEnumerable<>
, ele retornará o tipo passado. Para objetos, useGetType
. Para tipos, usetypeof
e chame este método de extensão no resultado.fonte
Eu sei que isso é um pouco antigo, mas acredito que este método irá cobrir todos os problemas e desafios declarados nos comentários. Os meus agradecimentos a Eli Algranti por inspirar o meu trabalho.
fonte
Esta é uma função recursiva que irá aprofundar primeiro na lista de tipos genéricos até obter uma definição de tipo concreto sem tipos genéricos internos.
Testei este método com este tipo:
ICollection<IEnumerable<ICollection<ICollection<IEnumerable<IList<ICollection<IEnumerable<IActionResult>>>>>>>>
que deve retornar
IActionResult
fonte
typeof(IEnumerable<Foo>)
. retornará o primeiro argumento genérico - neste caso .GetGenericArguments()
[0]
typeof(Foo)
fonte
é assim que eu costumo fazer (via método de extensão):
fonte
Esta é a minha versão de expressão de consulta Linq ilegível.
Observe que o método também leva
IEnumerable
em consideração o não genérico , ele retornaobject
neste caso, porque leva umaType
instância em vez de uma instância concreta como o argumento. A propósito, pois x representa o desconhecido , achei este vídeo interessante , embora seja irrelevante.fonte