2017-03-23 21 views
-2

隊名單<Base> =名單<Derived>&法案喜歡清單<Derived>

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

你的例子是錯誤的,'List Jill'沒有屬性'ClassRoom'它是一個列表... –

+0

你如何期待'public'字段對派生類不可見? –

+0

不,你不能讓人的行爲像老師,訪問屬性只屬於一個人對象上的老師將永遠不會工作.....我可能會重新考慮你的繼承在這裏......這是我認爲你不要使用繼承 –

回答

0

更新 - 既然你完全改變你的榜樣,我會更新我的答案,以反映新的榜樣。我只做過一次;所以對任何人來說,如果我的回答看起來與問題不同步,那是因爲OP在編輯過程中做了不必要的改動。


這裏有幾個問題。 List<Base>變量不可能引用List<Derived>實例。這是因爲,例如,List<Base>必須實施用於向List添加Base實例的操作,並且List<Derived>不能支持這樣的操作。

更一般地說,引用類型(聲明該變量的類型)定義調用代碼可以使用該值的接口。因此,如果您需要在您的示例中能夠說出city[0].NoOfRooms,則city必須聲明爲List<School>。 A School仍然可以存儲在List<Building>中,但是當您從這樣的列表中獲取某個項目時,在使用NoOfRooms屬性之前,您必須先嚐試投射到School。 (應該注意的是,如果你發現自己這樣做,這表明設計錯誤。)

你的問題的其他部分與隱藏Name屬性有關。

在某些語言中,您可以通過「私有繼承」獲得這樣的效果 - 但這不是C#中的事情。您可以做的最接近的事情是從Building派生出School而不是,但可能包含(私人)Building型字段或屬性。那麼,當然,根本不可能將School存儲在List<Building>中。

另一種方法是讓School覆蓋Name屬性,其中getter不返回任何值,這實際上更接近您的代碼註釋所建議的值。

0

作爲每評價你的問題,在一個對象的List<Building>不能任意地鑄造成School除非它最初被構造爲School對象(或從School派生的類)。考慮如果你有另一個類HospitalBuilding派生出來,並且擁有自己的屬性,說明NumberOfPatients會發生什麼情況,這是該列表中的一個對象。您只能將Hospital實例投射到School並調用僅在School上提供的屬性 - 這樣做沒有意義。

這就是說,你仍然可以有一個List<Building>存儲任何類型Building對象,包括那些衍生的(例如,你有一個包含BuildingSchoolHospital對象的混合清單)。然後,您可以通過Linq OfType(添加到文件的頂部using System.Linq;)獲得特定派生類型的對象的枚舉。因此,像buildingList.OfType<School>()這樣的東西只會給你枚舉School對象,你現在可以迭代並調用School上的方法/屬性。