将具体子项转换为在C#中具有泛型特化的父项

时间:2018-05-27 15:38:17

标签: c# generics events

我的代码很简单:

public interface IEvent {}

public class ObjectClickEvent : IEvent {        
    public Object Object;
    public ObjectClickEvent(Object object) {
        Object = object;
    }
}

public abstract class EventReceiver<T> where T : IEvent {
    protected readonly Controller Controller;
    protected EventReceiver(Controller controller) {
        Controller = controller;
    }

    public abstract void ReceiveEvent(T @event);
}

public class ObjectClickEventReceiver : EventReceiver<ObjectClickEvent> {
    public ObjectClickEventReceiver(Controller controller) : base(controller) {
    }
    public override void ReceiveEvent(ObjectClickEvent @event) {
    }
}

然后我想初始化控制器内的所有接收器

   var receivers = new List<EventReceiver<IEvent>>();
   var receiver = new LetterClickEventReceiver(this);
   receivers.Add(receiver);

但是出现了编译错误:

Argument type 'LetterClickEventReceiver' is not assignable to parameter type
'ScriptsV2.Core.Controller.EventReceivers.EventReceiver<IEvent>'

问题是,如果我声明我的具体接收器扩展了EventReceiver&lt; IEvent&gt;?为什么不能将子项添加到父对象列表中?

1 个答案:

答案 0 :(得分:0)

通过使基本接口的类型参数协变,可以使<A<Derived>A<Base>兼容。 out关键字执行此操作。

public interface EventReceiver<out T> where T : IEvent {...}

然后更新集合以使用这些接口而不是引用类。

差异:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/