简体   繁体   English

通用基类的隐式引用转换完成错误

[英]Implicit Reference Conversion Compliation Error with Generic Base class

I would like to be able to create the following class structure: 我希望能够创建以下类结构:

    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> { }

However this gives me the following error: 但是,这给了我以下错误:

The type 'School' cannot be used as type parameter 'T' in the generic type or method 'Container'. “学校”类型不能用作通用类型或方法“容器”中的类型参数“ T”。 There is no implicit reference conversion from 'School' to 'Building' 没有从“学校”到“建筑物”的隐式引用转换

What am I doing wrong here? 我在这里做错了什么?

Generic typing won't go as far as you need. 泛型类型无法满足您的需要。 As stated; 就像声明的那样; Building<Person> is not Building<Student> . Building<Person>不是Building<Student> However, this update to the last two classes will allow compilation: 但是,对最后两个类的更新将允许编译:

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

    class SchoolDistrict : Container<School, Student> { }

School is a Building<Student> . School是一栋Building<Student> Building<Student> is not a Building<Person> even though Student is a Person . 即使StudentPerson Building<Student>也不是Building<Person>

Introducing an interface will allow you to take advantage of Covariance in the generic declaration. 引入接口将使您能够利用泛型声明中的协方差。 This will allow Building to be treated as Building which is ultimately what you are wanting to achieve. 这将使建筑物被视为建筑物,这最终是您想要实现的目标。 Note that only interfaces support this via the 'out' modifier: 请注意,只有接口通过'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> { }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM