c# - 限制中间抽象类的继承

标签 c# inheritance

我有一个抽象类CreatureBehaviour,它提供了TakeTurn 方法。这样做的目标是决定生物应该做什么,并且它应该通过回调提供响应。这是因为响应可能需要玩家输入,因此它不应该阻止其他进程。

public abstract class CreatureBehaviour {

    public abstract void TakeTurn (Action<TurnAction> response);

}

继承自此,PlayerControl 类存储 response 回调以供以后决策。它的大部分内容都是不相关的,但最终它必须在玩家执行某些操作时调用响应

public class PlayerControl : CreatureBehaviour {

    Action<TurnAction> responseCallback;

    public override void TakeTurn(Action<TurnAction> response) {
        responseCallback = response;
    }

    // Various UI callbacks that can send something to "responseCallback" when appropriate.

}

所有非玩家生物也需要能够发送回调。为了安全起见,我想确保回调始终被命中,因此我创建了一个抽象 NonPlayerControl 类来确保响应:

public abstract class NonPlayerControl : CreatureBehaviour {

    protected abstract TurnAction TurnResponse ();

    public override void TakeTurn (Action<TurnAction> response) {
        response (TurnResponse ());
    }

}

有了这个,我所有的非玩家生物行为都可以从 NonPlayerControl 派生,并简单地实现 TurnReponse()。编译器保证所有脚本都会返回响应,而不是让回调挂起。请注意,PlayerControl 无法实现 TurnResponse(),因为它需要保证立即返回,而这会阻塞其他进程。

所以我想从 NonPlayerControl 甚至可能从 PlayerControl 派生其他类,但我不想意外地从 CreatureBehaviour 派生另一个类> 并有错过回调的风险。

有什么方法可以“某种程度地密封”CreatureBehaviour,以便它只能拥有这两个直接子级并阻止任何其他子级?如果没有,我可以在这里使用更好的模式吗?

最佳答案

您无法以“正常”方式为此做任​​何事情,但您可以考虑一个选择...

如果您只为 CreatureBehavior 类提供一个私有(private)构造函数,则将 PlayerBehaviorNonPlayerBehavior 嵌套在该类中,它们将有权访问私有(private)构造函数,但其​​他类不能...因此没有其他类可以从 CreatureBehavior 派生。

更简单的解决方案是:

  • CreatureBehavior 中的文档表明不应直接对其进行子类化
  • 编写单元测试来验证是否存在任何其他子类

当然,这只能测试您的代码,而不能测试其他程序集中的代码。如果您不需要其他程序集中的这些类,请将这些类设置为内部类而不是公共(public)类。即使您需要所有类都是公共(public)的,您也可以包含在 PlayerBehavior 和 NonPlayerBehavior 中实现的无操作抽象内部方法 - 这将阻止程序集外部的类派生自 CreatureBehavior,因为它们无法实现内部抽象方法。

关于c# - 限制中间抽象类的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45132001/

相关文章:

python - python3中具有不同签名的多重继承

c# - 进行 HTTP 隧道时如何保持连接打开

python - super() 和父类名有什么区别?

c# - 使用 AssemblyConfigurationEntry 在 PowerShell 中加载程序集时出现问题

c# - 在 C# .Net 中使用委托(delegate),当我用完 .Net 线程池中的线程时会发生什么情况?

ios - 父子关系与引用语义混淆(swift)

java - Java中如何不重写子类中的方法?

c++ - 子类获取父类(super class)私有(private)变量c++

c# - 从 xml 反序列化对象给出错误 : 'Memory stream is not expandable'

c# - 向 SQL Server 发送空参数