Reputation: 15658
I'd like to do something like this
void DoSomething<T>(T param)
{
if param is IEnumerable<?>
{
loop param and do stuff
}
}
I don't know what to do in the place of the question mark. And is it possible at all?
Upvotes: 7
Views: 6026
Reputation: 74530
You have to check the open generic type of each interface that the class implements, like so:
bool implements = typeof(T).GetInterfaces().Where(t => t.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any();
This will allow you to determine whether or not a type implements IEnumerable<T>
without actually knowing what the type T
is. Remember that the type can implement IEnumerable<T>
multiple times.
If you simply want the sequence of types that are type parameters for IEnumerable<T>
, you can change the above query to;
IEnumerable<Type> types = typeof(T).GetInterfaces().
Where(t => t.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).
Select(t => t.GetGenericArguments()[0]);
Upvotes: 0
Reputation: 10392
What you are looking for is :
if (T is IEnumerable) { .. }
but if you expect T to be IEnumerable all the time you can do:
void DoSomething<T>(T param) where T : IEnumerable
{
foreach (var t in param) { ... }
}
or checking the type of the values inside the IEnumerable:
public void DoSomething<T,U>(T val) where T : IEnumerable<U>
{
foreach (U a in val)
{
}
}
Without having to worry to check it yourself, the compiler will do it for you, which is one of the nice things of having a static type system and compiler :)
Upvotes: 12
Reputation: 30830
There are a few ways:
void DoSomething<T>(T param)
{
if (param is IEnumerable)
{
foreach (var item in (IEnumerable)param)
{
// Do something
}
}
}
void DoSomething<T>(T param)
{
if (param is IEnumerable<string>)
{
foreach (var item in (IEnumerable<string>)param)
{
// Do something
}
}
}
void DoSomething<T,TItem>(T param)
{
if (param is IEnumerable<TItem>)
{
foreach (var item in (IEnumerable<TItem>)param)
{
// Do something
}
}
}
Upvotes: 0