Convert / Cast IEnumerable to IEnumerable<T>
Solution 1:
Does your Method2
really care what type it gets? If not, you could just call Cast<object>()
:
void Method (IEnumerable source)
{
Method2(source.Cast<object>());
}
If you definitely need to get the right type, you'll need to use reflection.
Something like:
MethodInfo method = typeof(MyType).GetMethod("Method2");
MethodInfo generic = method.MakeGenericMethod(type);
generic.Invoke(this, new object[] {source});
It's not ideal though... in particular, if source isn't exactly an IEnumerable<type>
then the invocation will fail. For instance, if the first element happens to be a string, but source is a List<object>
, you'll have problems.
Solution 2:
You probably want to refactor your code to use IEnumerable.Cast<T>
Use it like this:
IEnumerable mySet = GetData();
var query = from x in mySet.Cast<int>()
where x > 2
select x;
Solution 3:
With .NET 4 you can just cast source
to dynamic
before passing it to method. This will cause the correct generic overload to be resolved at runtime without any ugly reflection code:
void Method(IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
Method2((dynamic)source);
}
}
As with Jon's second solution, this will only work if your source is actually an IEnumerable<T>
. If it is a plain IEnumerable
then you'll need to create another method that converts it to the correct IEnumerable<T>
type, as in the following solution:
IEnumerable<T> Convert<T>(IEnumerable source, T firstItem)
{
// Note: firstItem parameter is unused and is just for resolving type of T
foreach(var item in source)
{
yield return (T)item;
}
}
void Method(IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
dynamic firstItem = enumerator.Current;
dynamic typedEnumerable = Convert(source, firstItem);
Method2(typedEnumerable);
}
}