Unity3D EventManager:具有泛型类型的字典,派生自接口

时间:2017-05-04 09:50:23

标签: c# generics unity3d

美好的一天,

目前我正在为Unity项目开发一个EventSystem。 因此,我想使用UnityEvent(我听说去年有过改进)。

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

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。但我不知道如何更改代码以使其正常工作。我认为“哪里T:IEventData”修复了问题,但我认为它没有,因为T可能是派生类。

我的问题是: 是否可以添加通用BaseEvent,因为我打算这样做?

非常感谢提前!

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

我在visual studio中复制了你的代码,错误是:

Argument 2: can not covert from 'out BaseEvent<T>' to 'out BaseEvent<IEventData>'

下次发布问题时请提供此类错误消息

但是,在您所在的位置,我会将BaseEvent<T> tempEvent;的声明更改为BaseEvent<IEventData> tempEvent;,这应该会让您前进