C#中的协方差编译错误

时间:2013-06-30 07:11:15

标签: c#

为什么以下代码会抛出编译错误?根据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; }
    }

4 个答案:

答案 0 :(得分:4)

ListIList都不是协变量。

请改为尝试:

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