C# 泛型基类的隐式引用转换兼容错误

C# 泛型基类的隐式引用转换兼容错误,c#,generics,covariance,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>

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

    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> { }
公共类人物
{
公众人物(){}
公共字符串名称{get;set;}
}
班级学生{}
职业消防员:人{}
班主任{}
班级大楼,其中T:Person,new()
{
公共IEnumerable成员{get;set;}
}
班级学校:建筑{}
类别消防局:大厦{}
班级警察局{}
类容器,其中T:Building,new(){}
班级学区:集装箱{}
但是,这给了我以下错误:

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


我在这里做错了什么?

学校
是一座
建筑
<代码>建筑不是
建筑
,即使
学生

学校
是一座
建筑
<代码>建筑不是
建筑
,即使
学生

一般类型不会达到您需要的程度。如上所述<代码>建筑不是
建筑
。但是,对最后两个类的更新将允许编译:

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

    class SchoolDistrict : Container<School, Student> { }
类容器
其中U:人员,新()
其中T:Building,new(){}
班级学区:集装箱{}

通用键入不会达到您需要的程度。如上所述<代码>建筑不是
建筑
。但是,对最后两个类的更新将允许编译:

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

    class SchoolDistrict : Container<School, Student> { }
类容器
其中U:人员,新()
其中T:Building,new(){}
班级学区:集装箱{}

引入接口将允许您利用通用声明中的协方差。这将使建筑物被视为建筑物,这是你最终想要实现的目标。请注意,只有接口通过“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> { }
公共类人物
{
公众人物(){}
公共字符串名称{get;set;}
}
班级学生{}
班级建筑:IBuilding
其中T:Person,new()
{
公共IEnumerable成员{get;set;}
}
内部接口i编译,其中TPerson:Person{}
班级学校:建筑{}
类容器
其中T:i编译,new(){}
班级学区:集装箱{}

引入接口将允许您利用通用声明中的协方差。这将使建筑物被视为建筑物,这是你最终想要实现的目标。请注意,只有接口通过“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> { }
公共类人物
{
公众人物(){}
公共字符串名称{get;set;}
}
班级学生{}
班级建筑:IBuilding
其中T:Person,new()
{
公共IEnumerable成员{get;set;}
}
内部接口i编译,其中TPerson:Person{}
班级学校:建筑{}
类容器
其中T:i编译,new(){}
班级学区:集装箱{}

别忘了回答问题陈述,就像你对其他答案的回答一样。@BrettCaswell谢谢,我编辑了答案,试图使其与问题更加一致。别忘了回答问题陈述,就像你对其他答案的回答一样。@BrettCaswell谢谢,我编辑了答案,试图使其与问题更加一致。界面解决方案是一个很好的代码解决方案,但您并不是在要求代码解决方案。。请重新表述您的问题,询问您为什么会出现错误以及如何解决。。因此,您选择的答案在这个问题的上下文中是有意义的。接口解决方案是一个很好的代码解决方案,但您没有要求代码解决方案。。请重新表述您的问题,询问您为什么会出现错误以及如何解决。。所以你选择的答案在这个问题上是有意义的&你救了我的周末,谢谢你救了我的周末,谢谢