C# 强制一组 类 一起使用

C# enforce set of classes to be used together

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

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

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

例如,我想确保 CoolMode Input 不会传递给 NormalMode Judger。所以我的第一个解决方案是:

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, NormalScore, NormalInput} 相互使用?

The problem is that now NormalJudger can take any Input, not just NormalInput.

如果你的意思是有人可以创建自己的 Input<NormalMode> 实现并将其传递给 NormalJudger,那么实际上,你应该设计 NormalJudger 以便它可以判断任何有点像 Input<NormalMode>。这不是你创建 Input 作为抽象 class 的原因吗?这就是整个抽象点。 Judge不应该关心具体是什么Input,只要是Input<NormalMode>就可以了。 NormalMode 类型似乎只是类型系统区分您的类型的“标记”。那么,让它实际包含一些 data/logic,并让 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{}