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

C#: How to register a function from all subclasses of an interface to a single event in least redundant manner

实施 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)
    {

    }
}

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

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

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

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

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

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

    public abstract void FrameUpdate(float deltaTime);
}

在方法上加上 abstract 关键字本质上使它与接口一样工作:它需要子classes 来实现它而不是提供它自己的实现。