首页 > 解决方案 > 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 中一样。

提前致谢!

标签: c#unity3deventsinterface

解决方案


您不能自动订阅事件,但您可以将订阅代码移动到抽象类并在您要实现的每个类中继承它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");
    }
}

推荐阅读