C#: No casting within Generics?

Question!

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?");
}


Answers

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.



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.



string inherits from object but IList<string> does not inherit from IList<object> they are unrelated types and therefor you can't cast between them.

Just think what would happen if this worked:

// THIS CODE DOES NOT WORK
IList<object> list = new List<string>(); // this doesn't compile
list.Add(5); // because this is perfectly valid on IList<object> but not on IList<string>
By : Nir


This video can help you solving your question :)
By: admin