Search code examples
c#type-conversionupcasting

dynamically upcast arrays of identically typed instances


Given this linqpad code:

interface I {}
public class A : I {}
public class B : A {}
void Main()
{
    var i = new List<I>(new I[] { new A(), new B(), new A(), new B() });
    i.GroupBy(_ => _.GetType()).Select(_ => _.ToArray()).Dump();
}

What is the most efficient way to convert these items into IEnumerables of the actual derived types?

I have a method with signature DoStuffToArray<T>(IEnumerable<T> items)
I need to call it dynamically once for each of different types in the list i. It's a library method that needs to be called with the derived types, not the interface.

I have managed to get two typed arrays using this method, is there a better way?

var typeGroup = i.GroupBy(_ => _.GetType()).ToArray();
var arrays = typeGroup.Select(_ => Array.CreateInstance(_.Key, _.Count())).ToArray();   
for (int ai = 0; ai < typeGroup.Length; ai++)
{
    var grouping = typeGroup[ai].ToArray();
    int index = 0;
    Array.ForEach(grouping, _ => arrays[ai].SetValue(_, index++));
}
arrays.Dump("typed arrays");

Solution

  • You are looking for OfType<T>().

    var i = new List<I>(new I[] { new A(), new B(), new A(), new B() });
    var ayes = i.OfType<A>();
    var bees = i.OfType<B>(); 
    
    DoStuffToArray(ayes);
    DoStuffToArray(bees);
    

    Live example: http://rextester.com/HQWP13863