While I can upcast a string to an object, I cannot upcast an IList of strings to an IList of objects. How come? What to do now other that coping all items to a new IList?
static void ThisWorks()
{
IList<object> list = new List<object>();
list.Add("I can add a string since string : object");
}
static void ThisDoesNotWork()
{
// throws an invalid cast exception
IList<object> list = (IList<object>) new List<string>();
list.Add("I'm never getting here ... why?");
}
This is not possible as generics are invariant (as of C# 3.0).
You can workaround it with:
var objectList = list.Cast<object>().ToList();
Look at it like this: while a banana is a fruit, a basket of bananas is not a basket of fruit, since you can add oranges to the latter, but not the former. Your List<string>
has stronger constraints than a List<object>
.
Casting should always respect Liskow. For containers and iterators which do not admit modification, such casting is safe, but once things can be changed, you are skating close to the thin ice.
What you asked is essentially a question of Contravariance and Covariance. It is a concept in programming language design which talks about how methods and collections behave with respect to objects of two classes in the same inheritance hierarchy. Reading the Wikipedia article may help place your above curiosity in a larger, more general perspective.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With