tags:

views:

241

answers:

3

I am working on a transportation problem and cannot leap this hurdle. I am unable to convert the derived class StopsVisited to its base class Stops. The base class Stops is a collection of Stop. The derived class StopsVisited is a collection of StopVisited.

The element StopVisited derives from Stop (definitions not shown).

I have a non-generics workaround where I simplly derive StopsVisited from Stops, but the generics afford me more felixibility. I've tried to reduce it to its simplest form.

Base

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

}

Derived

public class StopsVisited : Stops<StopVisited>
{

}

The problem:

Stops<Stop> stops = new StopsVisited();

Gives me a

Error 1 Cannot implicitly convert type 'StopsHeirarchy.StopsVisited' to 'StopsHeirarchy.Stops'

Any help is appreciated.

A: 

C# 4.0 solves this problem by modifying the CLR to support it.

In the meantime, have an IStops interface (non-generic) and convert to it.

Ekevoo
Nope - covariance is only for interfaces, not for classes.
thecoop
+3  A: 

Personally, I wouldn't use inheritance to say that a Stop has been visited. I'd have a boolean data member to say that a Stop had been visited. It seems like a binary attribute - you've either been visited or you haven't.

Inheritance ought to be about different behaviors. Unless you can say that a visited Stop somehow behaves differently, I would advise against inheritance in this design.

duffymo
Indeed. Inheritance is overused in a lot of situations.
Anon.
This is the problem with presenting concise questions. StopVisited has many attributes that are not relevant to Stop (actual Latitude/Longitude when visited, VisitedOrder, actual ServiceTime...).
Tony D
I would argue that VisitedOrder should be an attribute of an aggregation of Stops, because the same Stop might participate in several journeys. Same goes for ServiceTime. And lat/long is fixed regardless of whether or not you've been visited. Still a poor design that should be rethought.
duffymo
Don't want to get into a flame war here, and I appreciate all help. But lat/lon is absolutely not the same. The customer may have been serviced at different location due to incorrect map data or driver knowledge. In fact we use that data to correct our maps. You must concede problem domain to the asker and stick to the technical aspects.
Tony D
I'm not required to concede any more than you're required to accept. I'm just a jamoke offering an opinion, often based on incomplete information; it's up to you to accept or reject. Relax - you can ignore what I said if you wish.
duffymo
+4  A: 

StopsVisited is not a subtype of Stops<Stop>; it's a subtype of Stops<StopVisited>, which is an entirely different thing. I agree with duffymo that subtyping is the wrong approach to your problem, but the specific feature you're asking about is called "covariance" or "output-safe" in C# 4; you can read about it here.

Craig Stuntz
Covariance will only be for interfaces, not classes. So it won't help here
thecoop
I wouldn't say "it won't help." Only that he'll have to use the feature as it's designed, not as he wrote the question.
Craig Stuntz