Search code examples
c#generic-collections

Cast collection of objects to collection of concrete class


Consider, that I've the following method:

public T Resolve<T>()
{
    var targetType = typeof(T);

    if (targetType.IsGenericType
          && targetType.GetGenerictTypeDefinition() == typeof(IEnumerable<>))
    {
        List<object> collection = this.ResolveCollection(targetType);

        return (T)(object)collection;
    }

    return (T)this.ResolveSingle(targetType);
}

Sample usage:

IEnumerable<IFoo> coll = myClass.Resolve<IEnumerable<IFoo>>();

It is obvious, that sample will throw exception of invalid cast, because of covariance - we cannot cast List<object> into IEnumerable<IFoo> despite collection contains implementations of IFoo only. Is there any workaround for that problem when using reflection and non-generic methods? I don't want to change Resolve signature so I don't have generic type of item to use LINQ Cast.


Solution

  • Found workaround:

    List<object> collection = this.ResolveCollection(targetType);
    
    var itemType = targetType.GetGenericArguments()[0];
    var listType =  typeof(List<>).MakeGenericType(itemType);
    
    var listInstance = Activator.CreateInstance(listType, new object[0]) as IList;
    foreach (var instance in collection) 
    {
        listInstance.Add(instance);
    }
    
    return (T)listInstance;
    

    Then, casting works like a chram.