问题
Let's say I've got an abstract class called Player
. Classes GameAPlayer
and GameBPlayer
inherit from Player
. In turn, a couple of abstract classes inherit from GameAPlayer
and GameBPlayer
respectively.
Let's say I've got another abstract class called Engine
which hosts List<Player>
. Classes GameAEngine
and GameBEngine
both inherit from Engine
. I know for a fact that all players in GameAEngine
will be of type GameAPlayer
, and that all players in GameBEngine
will be of type GameBPlayer
.
I cannot move List<Player>
into GameAEngine
and GameBEngine
as I'm using the list in Engine
itself.
Having to typecast Player
into GameAPlayer
and GameBPlayer
every time I use the list in their respective engines just seems unclean. Is there any way I can avoid having to do this?
回答1:
Change Engine
to Engine<TPlayer> where TPlayer : Player
.
Note that this will make base engines require generic type parameters everywhere; you can work around that using a non-generic interface.
Alternatively, make a GetPlayer
method in the derived classes that does the cast, and use that instead of the base list.
回答2:
You are experiencing the pain of what is known as the "parallel hierarchies problem". Object-oriented languages historically have done a poor job of dealing with the parallel hierarchies problem.
There's lots of interesting discussion about this problem and how various techniques deal with it; there is no slam-dunk solution. You might start by reading this discussion:
http://lambda-the-ultimate.org/node/1621
Also, there are lots of Stack Overflow questions about this area as well.
https://stackoverflow.com/search?q=parallel+hierarchies
来源:https://stackoverflow.com/questions/8509747/virtual-lists-in-c-sharp-to-avoid-typecasting-in-inherited-classes