C#强制将一组类一起使用

问题描述

这是我的用例。假设我有一款具有两种模式的游戏:CoolMode和normalMode。

两种游戏模式都非常不同,但是共有三个共同的对象:输入,得分和裁判。每种模式都有不同的实现方式,但是可以使用相同的代码从主游戏中调用

interface Judger{
  score Judge(Input i);
}
abstract class score {...}
abstract class Input {...}

例如,我想确保CoolMode输入不会传递给normalMode裁判。所以我的第一个解决方案是:

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>{...}

...

问题在于现在normalJudger可以接受任何输入,而不仅仅是normalInput。

如何强制(在编译时)类{normalJudger,normalscorenormalInput}相互使用?

解决方法

问题在于现在NormalJudger可以接受任何输入,而不仅仅是NormalInput。

如果这样意味着您可以让某人创建自己的Input<NormalMode>实现并将其传递给NormalJudger,那么实际上,您应该设计NormalJudger以便它可以判断任何一种Input<NormalMode>。这不是为什么您将Input创建为抽象类吗?这是抽象的全部要点。 Judge不必关心Input是什么特定类型,只要它是Input<NormalMode>。看来NormalMode类型只是类型系统的“标记”,用来区分您的类型。好吧,如何使它实际上包含一些数据/逻辑,并使Judge对其进行操作?


或者,您可以快速而又肮脏地使用Judge类型,以不同的方式进行参数化。除了在模式上参数化外,在ScoreInput上参数化:

public interface Judger<TScore,TInput> 
    where TScore: Score
    where TInput: Input{
  TScore Judge(TInput i);
}
public abstract class Score {}
public abstract class Input {}

interface NormalMode : GameMode {}
class NormalJudger:Judger<NormalScore,NormalInput>{
  public NormalScore Judge(NormalInput i) {return null;}
}
class NormalScore:Score{}
class NormalInput:Input{}