When I have a class Car
that implements ICar
and I have a List<Car>
why is it possible to call a method expecting IEnumerable<ICar>
but neither IList<ICar>
nor List<ICar>
?
IList<T>
is derived from IEnumerable<T>
and List<T>
implements IEnumerable<T>
.
So if I can assign List<Car>
to an IEnumerable<ICar>
because the compiler figures out that Car
is an ICar
why doesn't it work further down the inheritance / implementation chain?
using System.Collections.Generic;
internal class Program
{
private static void Main()
{
var fords = new List<Ford>() { new Ford("T") };
IEnumerableOfICar(fords);
IListOfICar(fords); //error CS1503: Argument 1: cannot convert from 'List<Ford>' to 'IList<ICar>'
ListOfICar(fords); //error CS1503
IEnumerableOfCar(fords);
IListOfCar(fords); //error CS1503
ListOfCar(fords); //error CS1503
IEnumerableOfFord(fords);
IListOfFord(fords);
ListOfFord(fords);
}
private static void IEnumerableOfICar(IEnumerable<ICar> cars)
{
foreach (var car in cars)
{
System.Console.WriteLine(car.Model);
}
}
private static void IListOfICar(IList<ICar> cars)
{
IEnumerableOfICar(cars);
}
private static void ListOfICar(List<ICar> cars)
{
IEnumerableOfICar(cars);
}
private static void IEnumerableOfCar(IEnumerable<Car> cars)
{
IEnumerableOfICar(cars);
}
private static void IListOfCar(IList<Car> cars)
{
IEnumerableOfICar(cars);
IListOfICar(cars); //error CS1503
ListOfICar(cars); //error CS1503
}
private static void ListOfCar(List<Car> cars)
{
IEnumerableOfICar(cars);
IListOfICar(cars); //error CS1503
ListOfICar(cars); //error CS1503
}
private static void IEnumerableOfFord(IEnumerable<Ford> cars)
{
IEnumerableOfICar(cars);
IEnumerableOfCar(cars);
}
private static void IListOfFord(IList<Ford> fords)
{
IEnumerableOfICar(fords);
IEnumerableOfCar(fords);
IListOfICar(fords); //error CS1503
IListOfCar(fords); //error CS1503
}
private static void ListOfFord(List<Ford> fords)
{
IEnumerableOfICar(fords);
IEnumerableOfCar(fords);
IListOfICar(fords); //error CS1503
ListOfICar(fords); //error CS1503
IListOfCar(fords); //error CS1503
ListOfCar(fords); //error CS1503
}
}
internal interface ICar
{
string Model { get; }
}
internal abstract class Car : ICar
{
public string Model { get; }
protected Car(string model) => this.Model = model;
}
internal class Ford : Car
{
public Ford(string model) : base(model) { }
}