Reputation: 10830
Why does the below code throw compile error? As per C# 4.0 Covariance should'nt such a conversion be allowed. List employeeList = managerList;
class Program
{
static void Main(string[] args)
{
List<Manager> managerList = new List<Manager>()
{
new Manager{ FirstName="ASFD", LastName="DSS", NoOfReportees=4},
new Manager{ FirstName="rrr", LastName="dsasde", NoOfReportees=22}
};
List<Employee> employeeList = managerList;
}
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Manager:Employee
{
public int NoOfReportees { get; set; }
}
Upvotes: 0
Views: 185
Reputation: 81253
List<T>
is invariant. You need IEnumerable<T>
which is covariant
.
Refer to the explanation here by Eric Lippert explained so nicely with zoo analogy -
A
List<Mammal>
cannot be converted to aList<Animal>
because you can put a lizard into a list of animals. AList<Mammal>
cannot be converted to aList<Giraffe>
because there might be a tiger in the list already.Therefore
List<T>
has to be invariant in T.However,
List<Mammal>
can be converted toIEnumerable<Animal>
(as of C# 4.0) because there is no method onIEnumerable<Animal>
that adds a lizard.IEnumerable<T>
is covariant in T.
Upvotes: 0
Reputation: 9698
Covariant interface must be declared explicitly using out
keyword. If you are using .Net 4.5, there is IReadOnlyCollection<T>
interface
IReadOnlyCollection<Employee> employeeList = managerList;
Noted that it is read-only, which is logical because we can read Employee
from List<Manager>
but we cannot add Employee
to it.
Upvotes: 0
Reputation: 101728
Think about it this way: If the assignment were allowed, you could do this:
List<Manager> managerList = new List<Manager>()
{
new Manager{ FirstName="ASFD", LastName="DSS", NoOfReportees=4},
new Manager{ FirstName="rrr", LastName="dsasde", NoOfReportees=22}
};
List<Employee> employeeList = managerList;
employeeList.Add(new Employee{ FirstName = "John", LastName = "Doe"});
and now your managerList would contain an item that was not a Manager
, violating the constraints of the list.
If it would suit your needs, you can, however, do this:
List<Employee> employeeList = new List<Employee>(managerList);
because it doesn't violate the original list.
Upvotes: 2
Reputation: 49105
Neither List
or IList
are covariants.
Try this instead:
IEnumerable<Employee> employeeList = managerList
More information on MSDN: Covariance and Contravariance (C# and Visual Basic)
Upvotes: 4