basically I\'m building a very generic T4 template and one of the things I need it to do is say print variable.ToString()
. However, I want it to evaluate lists and
If you don't care about object type and you are not in Generic method in C# 7.0+
if (item is IEnumerable<object> enumVar)
{
foreach (var e in enumVar)
{
e.ToString();
}
}
In C# < 7.0
if (item is IEnumerable<object>)
{
var enumVar = item as IEnumerable<object>;
foreach (var e in enumVar)
{
e.ToString();
}
//or you can cast an array to set values,
//since IEnumerable won't let you, unless you cast to IList :)
//but array version here
//https://stackoverflow.com/a/9783253/1818723
}
You have already accepted an answer however,since generic IEnumerable<T>
implements the non generic IEnumerable
you can just cast to that.
// Does write handle null? Might need some sanity aswell.
var enumerable = variable as System.Collections.IEnumerable;
if (enumerable != null)
foreach(var item in enumerable)
Write(item);
else
Write(item);
Since C# 7.0 you can also achieve this so:
if (variable is IEnumerable enumVar)
{
foreach (var e in enumVar)
{
...
}
}
In general, with no non-generic base type/interface, this requires GetType and a recursive look-up through the base types/interfaces.
However, that doesn't apply here :-)
Just use the non-generic IEnumerable (System.Collections.IEnumerable
), from which the generic IEnumerable (System.Collections.Generic.IEnumerable<T>
) inherits.
The other answers have pointed out the generic/non-generic IEnumerable difference but I should also point out that you will also want to test for String specifically because it implements IEnumerable but I doubt you'll want to treat it as a collection of characters.
You can actually test the base class of any generic type directly.
instance.GetGenericTypeDefinition() == typeof(IEnumerable<>)