C#:如何以最少冗余的方式将接口的所有子类中的函数注册到单个事件中



在实现Unity3D时,我有一个触发每个帧更新的事件FrameUpdateEventHandler

public delegate void FrameUpdateEventHandler(float deltaTime);
public class API
{
    public static FrameUpdateEventHandler FrameUpdateEvent;
    public void OnFrameUpdate(float deltaTime)
    {
        if(FrameUpdateEvent != null) FrameUpdateEvent(deltaTime);
    }
}
//Included as a script  in a single Unity component
public class UnityScript : MonoBehaviour
{
    void Update()
    {
        API.OnFrameUpdate(Time.deltaTime);
    }
}

我还有一个接口Entity,它包含一个用于API.FrameUpdateEvent 的事件处理程序的函数

public interface Entity
{
    public void FrameUpdate(float deltaTime);
}

我试图解决的问题是Entity的子类的每个实例都侦听API.FrameUpdateEvent

尽管简单的答案是对每个实现都这样做,

public class Dog : Entity
{
    public Dog()
    {
        API.FrameUpdateEvent += FrameUpdate;
    }
    public void FrameUpdate(float deltaTime)
    {
    }
}

在经历了许多不同的Entity之后,它会感觉重复:

public class Cat : Entity
{
    public Cat()
    {
        API.FrameUpdateEvent += FrameUpdate;
    }
    public void FrameUpdate(float deltaTime)
    {
    }
}
public class Bird : Entity
{
    public Bird()
    {
        API.FrameUpdateEvent += FrameUpdate;
    }
    public void FrameUpdate(float deltaTime)
    {
    }
}

我有一种非常强烈的感觉,我错过了一些可以让这个过程变得不那么多余的东西。

以下是一些想法,可以减少它的冗余(至少在我看来),但就我所知,这是不可能的:

  • 以某种方式将Entity.FrameUpdate(float)标记为自动添加到API.FrameUpdateEvent中作为事件处理程序

  • FrameUpdateEvent作为事件添加到Event中,但以某种方式将其链接回API.FrameUpdateEvent,以便其响应API.OnFrameUpdate(float)

    public interface Entity
    {
        event FrameUpdateEventHandler FrameUpdateEvent;
        public void FrameUpdate(float deltaTime);
    }
    public class Dog : Entity
    {
        public event FrameUpdateEventHandler FrameUpdateEvent;
        public Dog()
        {
            //API.OnFrameUpdate() wouldn't trigger this, afaik
            FrameUpdateEvent += FrameUpdate;
        }
        public void FrameUpdate(float deltaTime)
        {
        }
    }
    

无论如何,最重要的是,我不确定我是否以错误的方式处理了这个问题,所以请随意建议更改我正在使用的模型。

您可以使用抽象类而不是接口

如果实现Entity接口的类型尚未从其他类继承,则可以将Entity设为抽象类。

public abstract class Entity
{
    public Entity()
    {
        API.FrameUpdateEvent += FrameUpdate;
    }
    public abstract void FrameUpdate(float deltaTime);
}

abstract关键字放在方法上本质上使其工作方式与接口相同:它需要子类来实现它,而不是提供自己的实现。

相关内容

  • 没有找到相关文章

最新更新