2009-12-23 56 views
1

我正在處理運輸問題,無法跨越此障礙。我無法將派生類StopsVisited轉換爲其基類停止。基類Stops是Stop的集合。派生類StopsVisited是StopVisited的集合。無法將派生類轉換爲基類

StopVisited元素來自Stop(定義未顯示)。

我有一個非泛型的解決方法,我簡單地從停止派生StopsVisited,但泛型給了我更多的靈活性。我試圖將它簡化爲最簡單的形式。

基地

public abstract class Stops<T> where T : Stop 
{ 

} 

衍生

public class StopsVisited : Stops<StopVisited> 
{ 

} 

問題:

Stops<Stop> stops = new StopsVisited(); 

給了我一個

錯誤1無法隱式轉換類型'StopsHeirarchy.StopsVisited'爲'StopsHeirarchy.Stops'

任何幫助表示讚賞。

+0

如果停止只是停止對象的列表,爲什麼不使用IList? – 2009-12-23 21:56:58

+1

另一個泛型協方差問題...看到我的答案在這裏 - http://stackoverflow.com/questions/1443341/explicit-casting-problem/1443351#1443351 – thecoop 2009-12-23 22:16:29

回答

5

StopsVisited不是Stops<Stop>的亞型;它是Stops<StopVisited>的子類型,這是完全不同的東西。我同意duffymo的觀點:子類型是對你的問題的錯誤方法,但是你提到的特定功能在C#4中被稱爲「協方差」或「輸出安全」;你可以閱讀關於它here

+1

協方差只適用於接口,不適用於類。所以這不會在這裏幫助 – thecoop 2009-12-23 22:09:20

+0

我不會說「這不會幫助。」只有他必須按照設計使用該功能,而不是他寫這個問題。 – 2009-12-23 22:13:19

0

C#4.0通過修改CLR來解決此問題以支持它。

與此同時,有一個IStops接口(非通用)並將其轉換爲它。

+1

不 - 協方差只適用於接口,不適用於類。 – thecoop 2009-12-23 22:09:57

3

就我個人而言,我不會使用繼承來說停止已被訪問。我有一個布爾數據成員來說,已經訪問了Stop。這看起來像一個二元屬性 - 你已經被訪問過,或者你沒有。

繼承應該是關於不同的行爲。除非你可以說訪問停止某種行爲有所不同,否則我會建議在這種設計中不要繼承。

+0

確實。繼承在很多情況下被濫用。 – 2009-12-23 22:00:37

+0

這是提出簡明問題的問題。 StopVisited具有許多與Stop無關的屬性(訪問時的實際緯度/經度,VisitedOrder,實際ServiceTime ...)。 – 2009-12-23 22:02:59

+0

我認爲VisitedOrder應該是停靠點集合的屬性,因爲同一個停靠點可能會參與多個旅程。 ServiceTime也一樣。 lat/long是固定的,不管你是否被訪問過。仍然是一個糟糕的設計,應該重新思考。 – duffymo 2009-12-23 22:07:09