score:72

Accepted answer

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.

score:2

This is years later, but I solved the List<Object> problem.

void Method(IEnumerable source)
{
    var enumerator = source.GetEnumerator();
    if (enumerator.MoveNext())
    {
        MethodInfo method = typeof(MyClass).GetMethod("Method2");
        MethodInfo generic;
        Type type = enumerator.Current.GetType();
        bool sameType = true;

        while (enumerator.MoveNext())
        {
            if (enumerator.Current.GetType() != type)
            {
                sameType = false;
                break;
            }
        }

        if (sameType)
            generic = method.MakeGenericMethod(type);
        else
            generic = method.MakeGenericMethod(typeof(object));

        generic.Invoke(this, new object[] { source });
    }
}

score:5

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);
    }
}

score:11

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;

Related Query

More Query from same tag