c# - C# 事件/接口 - 无需订阅使用该接口的每个类即可获取回调
问题描述
我正在学习接口和事件,到目前为止一切都很好,但我有点卡在一个问题上。
在我使用 C# 接口的日子里,我习惯于声明要使用哪个接口,然后实现相关的方法,并且只要引发事件,它们就会自动回调。
例如 Unity 的IPointerClickHandler:
using UnityEngine; using UnityEngine.EventSystems;
public class Example : MonoBehaviour, IPointerClickHandler {
//Detect if a click occurs
public void OnPointerClick(PointerEventData pointerEventData)
{
//Output to console the clicked GameObject's name and the following message. You can replace this with your own actions for when clicking the GameObject.
Debug.Log(name + " Game Object Clicked!");
} }
现在,在查看有关如何使用事件和接口的示例时,我发现了以下示例:
发布者类和接口
using UnityEngine;
using System.Collections;
public class Publisher : MonoBehaviour
{
public delegate void ClickAction();
public static event ClickAction OnClicked;
void Start()
{
OnClicked();
}
}
public interface IBallManager
{
void Teleport();
}
订阅者类别:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Subscriber : MonoBehaviour, IBallManager
{
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnEnable()
{
Publisher.OnClicked += Teleport;
}
void OnDisable()
{
Publisher.OnClicked -= Teleport;
}
public void Teleport()
{
Debug.Log("EventTriggered");
}
}
我的问题如下:如何构建一个无需手动订阅和取消订阅事件的界面?有没有办法实现接口而不必使用 Publisher.OnClicked += Teleport; & Publisher.OnClicked -= 传送;在我使用 IBallManager 的每个班级中?只需实现接口并在事件引发时获取自动回调,就像在 Unity 的 IPointerClickHandler 中一样。
提前致谢!
解决方案
您不能自动订阅事件,但您可以将订阅代码移动到抽象类并在您要实现的每个类中继承它IBallManager
:
public abstract class BaseSubscriber: MonoBehaviour, IBallManager
{
public virtual void OnEnable()
{
Publisher.OnClicked += OnPublisherClicked;
}
public virtual void OnDisable()
{
Publisher.OnClicked -= OnPublisherClicked;
}
protected abstract void OnPublisherClicked();
}
在您的具体订阅者中继承它,如下所示,基类将为您完成订阅内容:
public class Subscriber: BaseSubscriber
{
public override void OnEnable()
{
// Do smth here
base.OnEnable();
}
public override void OnDisable()
{
// Do smth here
base.OnDisable();
}
protected override void OnPublisherClicked()
{
Debug.Log("EventTriggered");
}
}
推荐阅读
- c# - 无法加载文件或程序集以供项目参考
- django - 如何在 django 设置文件中添加相同站点无选项
- python-3.x - 在 Mayavi 中显示多个窗口
- reactjs - 用于 Visual 代码的 Microsoft Office 加载项调试器未找到 URL
- typescript - 打字稿 mapKey 和挑选
- python - 如何在seaborn中将标记列表显示为条形图
- reactjs - Virtual Swiper 无法与 React Hook 一起使用
- python - Spark:从 ColumnA 到 ColumnB 的字符串操作
- mysql - MARIADB yocto 项目:无法通过套接字“/var/lib/mysql/mysql.sock”连接到本地 MySQL 服务器 (2)
- algorithm - 在计算几何中表示垂直线的好方法?