通用基类的隐式参考转换补偿错误

时间:2015-06-05 18:29:43

标签: c# generics covariance

我希望能够创建以下类结构:

    public class Person
    {
        public Person() { }
        public string Name { get; set; }
    }

    class Student : Person { }
    class FireFighter : Person { }
    class PoliceOfficer : Person { }

    class Building<T> where T : Person, new()
    {
        public IEnumerable<T> Members { get; set; }
    }

    class School : Building<Student> { }
    class FireStation : Building<FireFighter> { }
    class PoliceStation : Building<PoliceOfficer> { }

    class Container<T> where T : Building<Person>, new() { }

    class SchoolDistrict : Container<School> { }

然而,这给了我以下错误:

类型'School'不能在泛型类型或方法'Container'中用作类型参数'T'。没有从“学校”到“建筑”的隐式参考转换

我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

通用打字不会根据您的需要进行。就像声明的那样; Building<Person>不是Building<Student>。但是,对最后两个类的更新将允许编译:

    class Container<T, U> 
        where U : Person, new()
        where T : Building<U>, new() { }

    class SchoolDistrict : Container<School, Student> { }

答案 1 :(得分:2)

SchoolBuilding<Student>。虽然Building<Student>Building<Person>,但Student不是Person

答案 2 :(得分:1)

介绍接口将允许您在泛型声明中利用协方差。这将使Building被视为Building,这最终是您想要实现的目标。请注意,只有接口通过'out'修饰符支持此功能:

    public class Person
    {
        public Person() { }
        public string Name { get; set; }
    }

    class Student : Person { }

    class Building<T> : IBuilding<T>
        where T : Person, new()
    {
        public IEnumerable<T> Members { get; set; }
    }

    internal interface IBuilding<out TPerson> where TPerson : Person { }
    class School : Building<Student> { }

    class Container<T>
        where T : IBuilding<Person>, new() { }

    class SchoolDistrict : Container<School> { }