I tried to make a conversion from object (the object contains a List<Apple>) to List<object>, and it fails with an exception:
Unable to cast object of type 'System.Collections.Generic.List[list_cast_object_test.Apple]' to type 'System.Collections.Generic.List[System.Object]'.
When I have replaced List with IEnumerable or IList (an interface) it works well, and I don't understand the difference....
The code looks like:
private void Form1_Load(object sender, EventArgs e) {
object resultObject = GetListAsObject();
// this cast works fine, it's normal...
var resAsIt = (List<Apple>)resultObject;
// also when I use a generic interface of 'object' cast works fine
var resAsIEnumerable = (IEnumerable<object>)resultObject;
// but when I use a generic class of 'object' it throws me error: InvalidCastException
var resAsList = (List<object>)resultObject;
}
private object GetListAsObject() {
List<Apple> mere = new List<Apple>();
mere.Add(new Apple { Denumire = "ionatan", Culoare = "rosu" });
mere.Add(new Apple { Denumire = "idared", Culoare = "verde" });
return (object)mere;
}
}
public class Apple {
public string Denumire { get; set; }
public string Culoare { get; set; }
}
Someone may explain me what it happens? What is the difference between cast to a generic interface and cast to a generic class?
It is because in IEnumerable<T> T is covariant while in List<T> T does not support Covariance.
See more about Covariance and Contraviance in c#
If you want to do thing like that you then have to use ToList<T>() overload which will wrap it to object type like:
List<object> result = resultObject.ToList<object>();
Here we are able to convert List<Apple> to List<Object> due to new List<T> creation where T is of type Object but we cannot cast the original List<Apple> reference to List<object>.
In this case it will create instance of Object type and will store reference to your type as reference of type object , but in case of Value Types or strcuts it will have boxing cost.
IEnumerable<T> is an interface, and since the type T is defined covariant (it is actually IEnumerable<out T>, note the out), you can cast the T to a base implementation, so IEnumerable<object is a valid cast on your list of type List<Apple>.
However, the type List<Apple> is not equal to the type List<object>, nor does the list List<Apple> derived from List<object>. The type parameter on List<T> is not covariant, hence that cast is invalid.
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