Here is my use case. Say I have a game with two modes: CoolMode and NormalMode.
Both game modes are very different but share three common objects: Input, Score, and Judger. Each mode would have different implementations, but could be called from the main game using the same code.
interface Judger{
Score Judge(Input i);
}
abstract class Score {...}
abstract class Input {...}
I wanted to make sure for example, a CoolMode Input would not be passed to a NormalMode Judger. So my first solution was:
interface GameMode{}
interface Judger<T> where T:GameMode{
Score<T> Judge(Input<T> i);
}
abstract class Score<T> where T:GameMode {...}
abstract class Input<T> where T:GameMode {...}
interface NormalMode{}
class NormalJudger:Judger<NormalMode>{
Score<NormalMode> Judge(Input<NormalMode> i);
}
class NormalScore:Score<NormalMode>{...}
class NormalInput:NormalInput<NormalMode>{...}
...
The problem is that now NormalJudger can take any Input, not just NormalInput.
How can I force (at compile time) the classes {NormalJudger, NormalScore, NormalInput} to be used with each other?