How to upcast an object of type IEnumerable<Foo> to IEnumerable<IFoo> if passed to the function as object?

c#, casting, generics

Solution

Before .NET 4.0, you can't - `IEnumerable<T>` is invariant before .NET 4.0.

With .NET 4.0, the code you've posted will work fine.

In .NET 3.5 you could use `Enumerable.Cast`:

public void F(object o)
{
    IEnumerable<IFoo> ifoos = ((IEnumerable) o).Cast<IFoo>();
}

Basically this uses the weakly typed `IEnumerable` (which both `IEnumerable<Foo>` and `IEnumerable<IFoo>` extend, so the cast will be fine) and then applies the `Cast<T>` method, which will basically chain another iterator to perform a cast on each item. That cast will certainly work if `Foo : IFoo`, so you'll be fine.

In .NET 2.0 you'd have to basically write `Cast` yourself, which is easy enough - particularly if you don't need to do any shortcuts:

public static IEnumerable<TResult> Cast<TSource, TResult>
    (IEnumerable<TSource> source)
{
    foreach(TSource item in source)
    {
        yield return (TResult) (object) item;
    }
}

The double cast is slightly awkward, but it works...

Problem

I'm trying to upcast a parameter passed as an object (which is an upcast of an object of type IEnumerable) to IEnumerable where Foo implements IFoo. Here is an example of what I'd like to do but it does not work. ``` public void F(object o) { //I know the object o is of type IEnumerable<Foo> where Foo implements IFoo IEnumerable<IFoo> ifoos = (IEnumerable<IFoo>) o); } ``` Is there a work around? I don't want to make the function F Foo specific but I cannot get it to cast to the Interface Unless I do: ``` IEnumerable<IFoo> ifoos = (IEnumerable<Foo>) o).Select( f => (IFoo) f); ``` Thanks Giuseppe

Original source