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