есть ли способ получить тип T
изIEnumerable<T>
посредством отражения?
например
у меня есть переменная IEnumerable<Child>
информация; я хочу получить тип ребенка через отражение
c#
generics
reflection
Усман Масуд
источник
источник
Ответы:
Таким образом,
печатает
System.String
.См. MSDN для
Type.GetGenericArguments
.Изменить: я считаю, что это решит проблемы в комментариях:
Некоторые объекты реализуют более одного универсального
IEnumerable
поэтому необходимо возвращать их перечисление.Изменить: хотя, я должен сказать, ужасная идея для класса реализовать
IEnumerable<T>
более одногоT
.источник
Я бы просто сделал способ расширения. Это сработало со всем, что я на него бросил.
источник
У меня была похожая проблема. Выбранный ответ работает для реальных экземпляров. В моем случае у меня был только тип (из
PropertyInfo
).Выбранный ответ не выполняется, если сам тип
typeof(IEnumerable<T>)
не является реализациейIEnumerable<T>
.В этом случае работает следующее:
источник
Type.GenericTypeArguments
- только для dotNet FrameWork версии> = 4.5. В противном случае - используйтеType.GetGenericArguments
вместо этого.Если вы знаете
IEnumerable<T>
(через дженерики), тогда простоtypeof(T)
должно работать. В противном случае (дляobject
или неуниверсальногоIEnumerable
) проверьте реализованные интерфейсы:источник
Type type
параметром , а не какobject obj
параметр , вы не можете просто заменитьobj.GetType()
с ,type
потому что если вы передаетеtypeof(IEnumerable<T>)
вы ничего не получите. Чтобы обойти это, проверьтеtype
сам, чтобы увидеть, является ли он общим,IEnumerable<>
а затем его интерфейсы.Большое спасибо за обсуждение. Я использовал его как основу для решения ниже, которое хорошо работает во всех интересующих меня случаях (IEnumerable, производные классы и т. Д.). Думал, что я должен поделиться здесь, если кому-то это тоже понадобится:
источник
someCollection.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()?.FirstOrDefault()
Просто используйте
typeof(T)
РЕДАКТИРОВАТЬ: Или используйте .GetType (). GetGenericParameter () для созданного объекта, если у вас нет T.
источник
Альтернатива для более простых ситуаций, когда будет либо
IEnumerable<T>
илиT
- обратите внимание на использованиеGenericTypeArguments
вместо вместоGetGenericArguments()
.источник
Это улучшение решения Eli Algranti в том, что оно также будет работать там, где
IEnumerable<>
тип находится на любом уровне в дереве наследования.Это решение получит тип элемента из любого
Type
. Если тип не являетсяIEnumerable<>
, он вернет переданный тип. Для объектов используйтеGetType
. Для типов используйтеtypeof
, а затем вызовите этот метод расширения для результата.источник
Я знаю, что это немного устарело, но я считаю, что этот метод покроет все проблемы и проблемы, указанные в комментариях. Благодарим Эли Альгранти за вдохновение в моей работе.
источник
Это рекурсивная функция, которая сначала просматривает список универсальных типов, пока не получит определение конкретного типа без внутренних универсальных типов.
Я тестировал этот метод с таким типом:
ICollection<IEnumerable<ICollection<ICollection<IEnumerable<IList<ICollection<IEnumerable<IActionResult>>>>>>>>
который должен вернуться
IActionResult
источник
typeof(IEnumerable<Foo>)
. вернет первый общий аргумент - в этом случае .GetGenericArguments()
[0]
typeof(Foo)
источник
вот как я обычно это делаю (с помощью метода расширения):
источник
Вот моя нечитаемая версия выражения запроса Linq.
Обратите внимание, что метод также принимает
IEnumerable
во внимание неуниверсальный тип ,object
в этом случае он возвращается , потому что он принимает вType
качестве аргумента не конкретный экземпляр, а. Кстати, поскольку x представляет неизвестное , я нашел это видео интересным, хотя и неуместным.источник