hi,
is there a way to retrieve type T
from IEnumerable<T>
through reflection?
e.g.
i have a variable IEnumerable<Child>
info; i want to retrieve Child's type through reflection
hi,
is there a way to retrieve type T
from IEnumerable<T>
through reflection?
e.g.
i have a variable IEnumerable<Child>
info; i want to retrieve Child's type through reflection
IEnumerable<T> myEnumerable;
Type type = myEnumerable.GetType().GetGenericArguments()[0];
Thusly,
IEnumerable<string> strings = new List<string>();
Console.WriteLine(strings.GetType().GetGenericArguments()[0]);
prints System.String
.
See MSDN for Type.GetGenericArguments
.
Edit: I believe this will address the concerns in the comments:
// returns an enumeration of T where o : IEnumerable<T>
public IEnumerable<Type> GetGenericIEnumerables(object o) {
return o.GetType()
.GetInterfaces()
.Where(t => t.IsGenericType == true
&& t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Select(t => t.GetGenericArguments()[0]);
}
Some objects implement more than one generic IEnumerable
so it is necessary to return an enumeration of them.
typeof(IEnumerable<Foo>)
.GetGenericArguments()
[0]
will return the first generic argument - in this case typeof(Foo)
.
Just use typeof(T)
EDIT: Or use .GetType().GetGenericParameter() on an instantiated object if you don't have T.
If you know the IEnumerable<T>
(via generics), then just typeof(T)
should work. Otherwise (for object
, or the non-generic IEnumerable
), check the interfaces implemented:
object obj = new string[] { "abc", "def" };
Type type = null;
foreach (Type iType in obj.GetType().GetInterfaces())
{
if (iType.IsGenericType && iType.GetGenericTypeDefinition()
== typeof(IEnumerable<>))
{
type = iType.GetGenericArguments()[0];
break;
}
}
if (type != null) Console.WriteLine(type);
Thank you very much for the discussion. I used it as a basis for the solution below, which works well for all cases that are of interest to me (IEnumerable, derived classes, etc). Thought I should share here in case anyone needs it also:
Type GetItemType(object someCollection)
{
var type = someCollection.GetType();
var ienum = type.GetInterface(typeof(IEnumerable<>).Name);
return ienum != null
? ienum.GetGenericArguments()[0]
: null;
}