我有以下接口:
然而,这个代码无法编译,因为我的泛型没有共同的基类型,这是有意设计的。任何对象都应该能够从
public interface INotificationHandler<T>
{
Task<T> Handle(string msg);
}
还有一些很高兴地实现它的类,如下所示:
public class FooHandler : INotificationHandler<Foo>
{
public Task<Foo> Handle(string msg) { return Task.FromResult<Foo>(new Foo()); }
}
public class BarHandler : INotificationHandler<Bar>
{
public Task<Bar> Handle(string msg) { return Task.FromResult<Bar>(new Bar()); }
}
我希望在一个集合中保存多个INotificationHandler实例,当我收到消息“foo”时,使用FooHandler,“bar”使用BarHandler,以此类推...
var notificationHandlers = new Dictionary<string, INotificationHandler<object>>();
notificationHandlers["foo"] = new FooHandler();
notificationHandlers["bar"] = new BarHandler();
...
public void MessageReceived(string type, string msg)
{
INotificationHandler<object> handler = notificationHandlers[type];
handler.Notify(msg).ContinueWith((result) => /* do stuff with a plain object */)
}
然而,这个代码无法编译,因为我的泛型没有共同的基类型,这是有意设计的。任何对象都应该能够从
MessageReceived
中的INotificationHandler
返回。
我如何使用无法隐式转换类型
FooHandler
到INotificationHandler<object>
。存在显式转换(是否缺少强制转换?)
INotificationHandler<T>
来处理它的具体实现的泛型类型,以便我不需要关心它们?
public interface INotificationHandler<out T>
吗? - Jerry FederspielT
在这个接口中具有协变性,因为Task<T>
是不变的。创建一个实现INotificationHandler<object>
的包装类并使用它。 - LeeTask<T>
是一个类而不是接口。你可以通过创建一个ITask<out T>
接口,一个实现它并包装一个Task<T>
的类,以及一个方法(比如在Task<T>
上的扩展方法),该方法接受一个Task<T>
并返回一个ITask<T>
来实现这一点。然而,这并不容易做到。在谷歌上搜索协变任务接口给了我这个,但我还没有尝试过。 - svinja