Skip to content

How to Add a Collection of a Derived Type/Subclass with Generic List AddRange()

Another gem today, when attempting to add a subclass collection to a base type list using the AddRange() method you may encounter the following error using this code:

List<BaseClassA> baseList = new List<BaseClassA>();
baseList.AddRange((IEnumerable<SubClassB>) subList); // Where 'SubClassB' is a class deriving from 'BaseClassA'

System.InvalidCastException was unhandled:
Message=”Unable to cast object of type ‘System.Collections.Generic.List`1[MyNamespace.BaseClassA]‘ to type ‘System.Collections.Generic.IEnumerable`1[MyNamespace.SubClassB]‘.”

Ah! You might think, well that's obvious, you are casting to IEnumerable when it's expecting List, well you would be wrong, because AddRange explicitly asks for an IEnumerable<T> type.
Well it turns out, we aren't even getting as far as evaulating the parameter given correctly, as "(IEnumerable<SubClassB>) subList" is actually failing before anything else.

If we QuickWatch that by itself, we can see a very similar error:

Cannot cast 'SubClassB' (which has an actual type of 'System.Collections.Generic.List<SubClassB>') to 'System.Collections.Generic.IEnumerable<BaseClassA>'

So what could be going on?

Well from what I have read, apparently .NET does not [yet] support covariance, which I believe is what is stopping us from achieving our goal above, and the word on the street is we might expect to see it in .NET 4.0.

Now there is a way around this, not all is lost if we didn't have an answer (luckily I do below). To illustrate just how annoying this error is, we can do a bit more hard work for the compiler and achieve a populated list successfully full of SubClassA's...

foreach (var subClass in subList)
{
    baseList.Add(subClass);
}

That works perfectly:

baseList:
Count = 2
  [0]: {MyNamespace.SubClassA}
  [1]: {MyNamespace.SubClassA}

So with that said, and a long-way-around demonstrated, there has to be an easier way that IS available right now? Well yep, now LINQ has came along in .NET 3.0+ we can use the extension method Cast<T>... Let's check it out.

baseList.AddRange(subList.Cast<BaseClassA>());

That's it! You will receive a populated list just like the one done with individual Add's in the previous example!

VN:F [1.9.10_1130]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.10_1130]
Rating: 0 (from 0 votes)
How to Add a Collection of a Derived Type/Subclass with Generic List AddRange(), 5.0 out of 5 based on 1 rating
Bookmark and Share
kick it on DotNetKicks.com
Shout it

NOW, FOR A WORD FROM OUR SPONSORS

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*

My name is Graham O'Neale and I'm a software architect from Gold Coast, Australia. I am an overtime thinker, full time coder and awake part time in the real world. I have a keen interest in software development, particularly in the realm of programming (C#, ASP.NET, ASP.NET MVC, LINQ (2 SQL), Entity Framework, Silverlight, Blend, WCF, WPF) and a keen interest in the cutting edge and innovation. I have a new found love for design patterns, ALT.NET practices and well crafted software architecture. The purpose of this blog is to express any thoughts, findings, tips and gripes along my travels in the wonderful world of coding and technology...