2009-12-23 106 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