c# - Unity3D 事件管理器 : Dictionary with Events of generic Type that derives from an interface

标签 c# generics unity-game-engine

美好的一天,

目前我正在为 Unity 项目开发 EventSystem。 因此我想利用 UnityEvent(据我所知,它在去年得到了改进)。

EventManager 应尽可能通用,因此通过事件类型注册事件。因此,我创建了一个派生自 UnityEvent 的通用 BaseEvent。类型应为IEventData,它是定义EventData对象的接口(interface)。

public class BaseEvent<T> : UnityEvent<T> where T : IEventData {}

public interface IEventData {}

public struct SomeEventData : IEventData
{
    public readonly float someFloat;
    public readonly bool someBool;

    public SomeEventData(float param1, bool param2)
    {
        someFloat = param1;
        someBool = param2;
    }
}

现在我在 Eventmanager 中遇到以下问题。 由于 EventManager 拥有一个包含 BaseEvent 的字典,因此在尝试从 AddListener 等通用方法访问它们时会出现错误。

public class EventManager {
private Dictionary<System.Type, BaseEvent<IEventData>> m_events;

private static EventManager m_instance;

public static EventManager Instance {
    get {
        if (m_instance == null) {
            m_instance = new EventManager();
        }
        return m_instance;
    }
}

public static void AddListener<T>(BaseEvent<T> listener) where T : IEventData {             
    BaseEvent<T> tempEvent;     

    if (Instance.m_events.TryGetValue(typeof(T), out tempEvent)) {
        tempEvent.AddListener(listener);
    }
    else {
        tempEvent = new BaseEvent<T>();
        tempEvent.AddListener(listener);
        Instance.m_events.Add(typeof(T), tempEvent);
    }
}

这个错误是显而易见的。无法从 T 的 BaseEvent 转换为 IEventData 的 BaseEvent。但我不知道如何更改代码才能使其正常工作。我认为“where T : IEventData”解决了问题,但我认为它没有,因为 T 可能是派生类。

我的问题是: 是否可以按照我的意愿添加通用 BaseEvents?

非常感谢!

最佳答案

您面临的问题是协方差,目前 Unity 中提供的 .Net 子集不支持协方差。

您的问题已得到很好的解释 here

关于c# - Unity3D 事件管理器 : Dictionary with Events of generic Type that derives from an interface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43779494/

相关文章:

unity-game-engine - 重力的作用很奇怪

c# - 将Texture2D转换为视频

unity-game-engine - 如何以编程方式在 Unity 3D 中设置 UI 文本的字体

c# - 如何远程启动不同系统上的应用程序?

c# - 设置和获取属性和常量差异

java - 静态泛型方法,类型推断导致 java.lang.VerifyError : Verifier rejected class

Java通用接口(interface)层次结构

java - 列表与数组列表

c# - 用于 C# 的发送网格 API

c# - 如何填补列表中属性值的空白?