Search code examples
c#covariance

Pass a List of a class into method with list of an abstract base class as a parameter (Covariance)


I have classes that inherit from an abstract base class, and I want to pass a List of any of those classes into a method that that has a List of the base class as a parameter. How can I make that happen?

Here is want I've tried -

public abstract class MyBaseClass {}

public class MyClass1 : MyBaseClass {}

//Inside another class
public void MyMethod(List<MyBaseClass> listOfBaseClass){}

//Inside another class
List<MyClass1> myClass1List = new List<MyClass1>();
MyMethod(myClass1List); //ERROR HERE, This method call does not compile

Is there anyway to accomplish what I am trying to do?


Solution

  • If you want to pass collections of derived types of MyBaseClass, you'll need to change the signature

    public void MyMethod(List<MyBaseClass> listOfBaseClass){}
    

    To a type which supports covariance, such as IEnumerable or IReadOnlyCollection, e.g.:

    public void MyMethod(IEnumerable<MyBaseClass> listOfBaseClass){}
    

    This is because List is invariant, whereas IEnumerable is covariant. The reason why the compiler is strict is because List allows for change to the collection, e.g. if MyMethod would be allowed to do this:

    public void MyMethod(List<MyBaseClass> listOfBaseClass)
    {
        listOfBaseClass.Add(new AnotherClass());
    }
    

    Where AnotherClass was another subclass of MyBaseClass, it would break the caller's collection which was supposed to be of List<MyClass1>();.

    More about this here