在不知道基类存在的情况下调用继承基类的每个类

本文关键字:基类 继承 情况下 不知道 存在 调用 | 更新日期: 2023-09-27 17:53:59

我正在尝试在websocket服务器中实现类似unity3d的系统。它们有一个叫做MonoBehavior的基类,所有的类都从这个基类继承。

这些类有特定的函数(start, ongui, update),这些函数在特定的时间间隔被调用。

每个从该类继承的类都有自己的函数被调用(update每帧被调用)

我想创建一个基类,然后调用它,让每个包含函数的类自动调用,就像unity3d那样。我试过谷歌搜索,但不知道这种类型的行为与类被调用,甚至得到一个有用的结果

在不知道基类存在的情况下调用继承基类的每个类

为什么不实现一个静态Manager类呢?

public static class CallManager
{
    public static HashSet<Callable> callables = new HashSet<Callable>();
    // Other management code...
}

有一个基类,所有你的可调用类的子类,自动添加每个新的实例到你的CallManager管理的可调用对象集:

public abstract class Callable
{
    public Callable()
    {
        OnCreate();
    }
    protected void OnCreate()
    {
        CallManager.callables.Add(this);
    }
    public abstract void Start();
    public abstract void OnGUI();
    public abstract void Update();
}

现在,每当有人创建新的Callable时,基础Callable构造器将用新的Callable更新CallManager。完整的示例程序如下:

class Caller
{
    public static void Main(string[] args)
    {
        Callee1 c1 = new Callee1();
        Callee2 c2 = new Callee2();
        foreach (Callable c in CallManager.callables)
        {
            c.Start();
            c.OnGUI();
            c.Update();
        }
    }
}
public abstract class Callable
{
    public Callable()
    {
        OnCreate();
    }
    protected void OnCreate()
    {
        CallManager.callables.Add(this);
    }
    public abstract void Start();
    public abstract void OnGUI();
    public abstract void Update();
}
public static class CallManager
{
    public static HashSet<Callable> callables = new HashSet<Callable>();
}
public class Callee1 : Callable
{
    public Callee1()
    {
    }
    public override void Start()
    {
        Console.WriteLine("Callee1::Start");
    }
    public override void OnGUI()
    {
        Console.WriteLine("Callee1::OnGUI");
    }
    public override void Update()
    {
        Console.WriteLine("Callee1::Update");
    }
}
public class Callee2 : Callable
{
    public Callee2()
    {
    }
    public override void Start()
    {
        Console.WriteLine("Callee2::Start");
    }
    public override void OnGUI()
    {
        Console.WriteLine("Callee2::OnGUI");
    }
    public override void Update()
    {
        Console.WriteLine("Callee2::Update");
    }
}

可以这样写:

public static class Caller {
    public static event EventHandler Updating;
    public static Update() {
        var handler = Updating;
        if (handler ¡= null) handler(null, EventArgs.Empty);
    }
 }
public abstract class Base {
    protected Base() {
        Caller.Updating += Caller_Updating;
    }
    void Caller_Updating(object sender, EventArgs e) {
        Update();
    }
    protected abstract Update();
 }

据我所知,您希望所有派生类都调用该方法。这样当你呼叫来电者时。

我相信您指的是模板方法设计模式,通常也称为钩子。它是很多很多框架的基石。它的工作原理是这样的:

public abstract class BaseClass
{
    public void Start()
    {
        //execute start logic
        DoThis();
        DoThat();
        //call base class's hook
        OnStart();
    }
    protected abstract void OnStart();
}

你声明了一个派生类必须实现的抽象方法OnStart。当基类的Start方法被调用时,基类调用钩子,然后由派生类执行。

如果你想让重写钩子成为可选的,那么你可以用一个空的实现声明虚方法,即protected virtual void OnStart() { }

可能还值得一提的是,这是好莱坞原则的核心:"不要打电话给我们,我们会打电话给你!"(也就是说,你不调用框架的类——框架会调用你!)