John said:
here is GameElement
public class GameElement : CubeSpace3.GameElement<GameObject>
I think my question is:
when you derive from a base class
and arguments of the overridden methods should also "follow" the
derived class in some way
That's a statement, not a question. And if you are asking how to
accomplish the statement, you'll have to be more specific about what you
mean by "in some way" and why this is important.
so where the base class implemented:
bool Enumerate(ref BaseType)
in the derived class I would want:
bool Enumerate(ref DerivedType)
how can I:
1) (ideal) not have to overload the method and not have clients of the
class go through casting hell
First you need to explain why it is your clients of the code do need to
"go through casting hell". Explain it using specific, technical
language, not ambiguous, imprecise language.
2) (second best) overload the method without that horrible double cast
and copy?
it seems I am writing quite a lot of code just to make using my
derived classes simple and readable etc.
is that the price I have to pay?
To write code that's awkward? Yes. There's a price to pay for that.
Without a proper code example, it's not possible to know for sure. But
it actually seems to me you have two different problems: the question of
inheritance, and the question of generic variance.
The former is simpler, so I'll focus on that. And specifically, you
seem to want to override a base class virtual method using a type
different from that used in the base class.
The reason that's awkward is that it completely side-steps and ignores
the point of having a virtual method: to allow for polymorphic behavior.
Polymorphism is useful when you only need to know the base type, and can
successfully use it without referring to the actual derived type. As
soon as you insert into your code some dependency on the actual derived
type, the polymorphism becomes pointless.
Generics offer a different kind of "polymorphism" in that rather than
inheriting a class, you simply get a different class or method depending
on one or more types. This allows for a common implementation to be
shared among pieces of code that vary only according to the type
parameter for the generic code.
In the same way that having virtual method usages depend on the
inherited type is awkward and pointless, so too is having generic code
that depend specifically on the type parameter. Once you start
special-casing type parameters, you might as well make the code non-generic.
There are some exceptions to this, especially in the case of generics
(where you can still leave nearly all the code substantially the same,
having a special-case section only for a very specific and unusual
case). But even there, the exceptions always beg the question: why are
you using virtual methods or generics when the code would work better
without them?
Basically: your question has the form of "I have decided on a particular
implementation, and I want to force this implementation to work".
Whereas a better question would have the form "I have this high-level
problem, and I would like an implementation that is better than the one
I have already decided on".
Without knowing exactly what the high-level problem description, the
best anyone can come up with is "yup, that's awkward". You picked the
implementation, now you have to live with it.
Pete