类
public class Building
{
public string Name = "Not To Be Seen";
...
}
public class School: Building
{
public int NoOfRooms = 200;
public string Address = "123 Main St.";
...
}
目标(n其他一些类/用例)
// This is a simple example, in reality this code is far more complex
// the class "School" is private from the program
List<Building> city = new List<School>();
// city will only have properties of the class School (or at least those are the only properties seen)
Console.WriteLine(city[0].NoOfRooms.ToString()) // Outputs 200
Console.WriteLine(city[0].Name) // Should not output anything
根据正确转换列表,这似乎应该是非常可能的。但是,我似乎无法弄清楚如何让它工作。它似乎涉及协方差,但我不想要一个不可变的列表或类型。 C#不容易提供这种转换(即基类可以完全模仿派生类)?
由于
答案 0 :(得分:0)
更新 - 由于您完全更改了示例,我将更新我的回答以反映新示例。我这样做只有一次;所以对于任何阅读的人来说,如果我的回答似乎与问题不一致,那是因为OP在编辑期间进行了不必要的更改。
这里有一些问题。 List<Base>
变量无法引用List<Derived>
实例。这是因为,例如,List<Base>
必须实施将Base
实例添加到List
的操作,而List<Derived>
不能支持此类操作。
更一般地说,引用类型(声明变量的类型)定义了调用代码可以使用该值的接口。因此,如果您需要在示例中说出city[0].NoOfRooms
,则必须将city
声明为List<School>
。 School
仍然可以存储在List<Building>
中,但是当您从此类列表中获取项目时,您必须先尝试转换为School
才能使用NoOfRooms
属性。 (并且应该注意的是,如果您发现自己这样做,则表明存在设计错误。)
问题的另一部分与隐藏Name
属性有关。
在某些语言中,你可以通过&#34;私人继承获得这样的效果&#34; - 但这不是C#中的事情。您可以做的最接近的事情是从School
派生Building
而不是,但可能包含(私有)Building
类型的字段或属性。然后,当然,根本不可能在School
中存储List<Building>
。
另一种方法是让School
使用一个不返回任何内容的getter覆盖Name
属性,这实际上更接近代码注释所暗示的内容。
答案 1 :(得分:0)
根据您的问题的评论,List<Building>
中的对象不能被任意强制转换为School
,除非它最初被构造为School
对象(或派生类)来自School
)。考虑如果你有另一个名为Hospital
的类派生自Building
并且有自己的属性说NumberOfPatients
并且这是该列表中的一个对象会发生什么。您无法将Hospital
个实例投射到School
并仅在School
上调用属性 - 这样做是没有意义的。
也就是说,您仍然可以List<Building>
存储任何类型的Building
个对象,包括派生的对象(这样您就会有一个包含Building
的混合列表,School
和Hospital
个对象)。然后,您可以通过Linq OfType
获取特定派生类型的对象的枚举(添加到文件的顶部using System.Linq;
)。因此,类似buildingList.OfType<School>()
的内容只会为您提供School
个对象的枚举,您现在可以迭代这些对象并调用仅在School
上可用的方法/属性。