泛型和接口的问题以及无法将具体类型转换为接口

问题描述 投票:0回答:1

我有以下场景

public interface IEvent {}
public interface IEventHandler<T> where T : IEvent {
   void Handle(T evt);
}

public class ItemCreatedEvent : IEvent {}
public class ItemCreatedEventHandler : IEventHandler<ItemCreatedEvent> {
   void Handle(ItemCreatedEvent evt) { ... }
}

以下所有内容都可以:

  • 我可以获得事件的具体类型(即我可以获得 ItemCreatedEvent 类型的对象)
  • 基于此,我可以确定处理程序的具体类型(即 ItemCreatedEventHandler)
  • 我可以创建这种类型的实例(Activator.CreateInstance(handlerType))

当我想在此实例上调用 .Handle() 方法时,问题就出现了

...

var handler = (IEventHandler)Activator.CreateInstance(handlerType);
handler?.Handle(evt);

这给我带来了以下问题:

  • 如果我投射到
    (IEventHandler)
    Handle()
    方法是未知的
  • 如果我转换为
    (IEventHandler<IEvent>)
    ,它会失败,因为“无法从
    ItemCreatedEventHandler
    隐式转换为
    IEventHandler<IEvent>

从我到目前为止发现的情况来看,这与类型不变性有关,但我没有找到任何可以帮助我解决问题的东西。

谢谢!

c# .net generics
1个回答
0
投票

如果我转换为

(IEventHandler<IEvent>)
,它会失败,因为“无法从
ItemCreatedEventHandler
隐式转换为
IEventHandler<IEvent>

那是因为对于

IEventHandler<T>
T
是不变的,所以
IEventHandler<ItemCreatedEvent>
不是
IEventHandler<IEvent>

在您的示例中,不可能使

T
协变,因为
T
用于接口定义中的输入位置,因此这样做不是类型安全的:

void Handle(T evt);

一旦你在这里开始反思,你就需要继续反思:

var handler = Activator.CreateInstance(handlerType);
var method = handler.GetMethod("Handle");
method.Invoke(handler, new object[] { evt });
© www.soinside.com 2019 - 2024. All rights reserved.