0

为什么下面的代码会抛出编译错误?根据 C# 4.0 Covariance,不应该允许这样的转换。列出员工列表 = 经理列表;

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; }
    }
4

4 回答 4

4

两者都不是ListIList变量。

试试这个:

IEnumerable<Employee> employeeList = managerList

有关 MSDN 的更多信息:协变和逆变(C# 和 Visual Basic)

于 2013-06-30T07:18:52.150 回答
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 将包含一个不是 a 的项目,这Manager违反了列表的约束。

但是,如果它适合您的需要,您可以这样做:

List<Employee> employeeList = new List<Employee>(managerList);

因为它不违反原始列表。

于 2013-06-30T07:22:28.327 回答
0

List<T>是不变的。你需要IEnumerable<T>的是covariant.

请参阅Eric Lippert在这里用动物园类比很好地解释的解释 -

AList<Mammal>无法转换为 a List<Animal>,因为您可以将蜥蜴放入动物列表中。AList<Mammal>无法转换为 a List<Giraffe>,因为列表中可能已经有老虎。

因此List<T>在 T 中必须是不变的。

但是,List<Mammal>可以转换为IEnumerable<Animal>(从 C# 4.0 开始),因为没有IEnumerable<Animal>添加蜥蜴的方法。IEnumerable<T>在 T 中是协变的。

于 2013-06-30T07:35:01.483 回答
0

协变接口必须使用out关键字显式声明。如果您使用的是 .Net 4.5,则有IReadOnlyCollection<T>接口

IReadOnlyCollection<Employee> employeeList = managerList;

注意它是只读的,这是合乎逻辑的,因为我们可以从中读取EmployeeList<Manager>我们不能添加Employee到它。

于 2013-06-30T14:31:43.823 回答