为什么以下代码会抛出编译错误?根据C#4.0,协方差不应允许这样的转换。 列出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; }
}
答案 0 :(得分:4)
List
或IList
都不是协变量。
请改为尝试:
IEnumerable<Employee> employeeList = managerList
有关MSDN的更多信息:Covariance and Contravariance (C# and Visual Basic)
答案 1 :(得分:2)
以这种方式思考:如果允许分配,您可以这样做:
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"});
现在您的managerList将包含一个不是Manager
的项目,违反了列表的约束。
如果它符合您的需求,您可以这样做:
List<Employee> employeeList = new List<Employee>(managerList);
因为它没有违反原始列表。
答案 2 :(得分:0)
List<T>
是不变的。您需要IEnumerable<T>
covariant
。{/ p>
请参阅here解释Eric Lippert对动物园类比的解释 -
List<Mammal>
无法转换为List<Animal>
,因为您 可以将蜥蜴放入动物名单中。List<Mammal>
不可以 转换为List<Giraffe>
,因为可能有一只老虎 列表已经。因此
List<T>
必须在T中保持不变。但是,
List<Mammal>
可以转换为IEnumerable<Animal>
(截至 C#4.0)因为IEnumerable<Animal>
上没有添加的方法 一只蜥蜴IEnumerable<T>
在T中是协变的。
答案 3 :(得分:0)
必须使用out
关键字明确声明协变接口。如果您使用的是.Net 4.5,则有IReadOnlyCollection<T>
接口
IReadOnlyCollection<Employee> employeeList = managerList;
注意它是只读的,这是合乎逻辑的,因为我们可以从Employee
读取List<Manager>
,但我们无法向其添加Employee
。