How to assign List <DerivedClass> to IEnumerable <BaseClass> parameter?

I understand that the derived class List <> cannot be directly assigned to List <> of the base class. But how does it allow you to assign the same class List <> from the derived class to the parameter of the IEnumerable <> base class.

public class Base {} public class Derived : Base {} public class Test { // inside some method... List<Derived> someElements; ReadElements(someElements); public void ReadElements(List<Base> elements) // this throws compile error {...} public void ReadElements(IEnumerable<Base> elements) // this one works {...} } 

I know List is an IEnumerable implementation and supports indexing and modifying elements, but it seems like I don't understand this part? Can someone explain? Thanks.

+4
source share
4 answers

Since the declaration of IEnumerable<T> actually :

 public interface IEnumerable<out T> : IEnumerable 

... and the out bit means that T is covariant and accepts subtypes.

While the declaration of List<T> has no annotation for deviations, and therefore T is invariant.

+7
source

IList and List do not determine their T as the out , and IEnumerable . List is a class, so it cannot have out , and IList does not define out , because it accepts inputs of type T

Put an easier way to get back T from IEnumerable , but you can put it in T in IList , because of this IEnumerable doesn't matter if you are less specific, but IList does. (This is actually needed, see @ChrisShain's answer for a link to how covariance and contravariance work).

+2
source

Consider this code, which in itself is completely legal:

 public void AddElements(List<Base> elements) { Base item = new Base(); elements.Add(item); } 

But what happens if you call it this:

 List<Derived> elements = new List<Derived>; AddElements(elements); 

The Base class is not inherited from Derived and therefore cannot be added to the elements list. This is a potential problem, therefore illegal.

On the other hand, IEnumerable<Base> only provides methods for reading the collection, not writing to it, so this contradiction cannot be satisfied.

+2
source
+1
source

Source: https://habr.com/ru/post/1390728/


All Articles