动态通用接口转换 [英] Dynamic generic interface cast

查看:154
本文介绍了动态通用接口转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想动态发现和注册接口实现。为了论证,我有两种类似于这些的方法:

I want to dynamically discover and register interface implementations. For the sake of argument I have two methods similar to these:

public void Register<TEvent>(IHandler<TEvent> handler) where TEvent : IEvent

public void Register<TEvent>(Action<TEvent> action) where TEvent : IEvent
{
    Register<TEvent>(handler.Handle);
}

接口如下:

public interface IHandler<T> where T : IEvent
{
    void Handle(T args);
}

public interface IEvent
{
}

然后我有具体的实现像:

Then I have the concrete implementations like:

public class ChangedEvent : IEvent
{...}

public class ChangedHandler : IHandler<ChangedEvent>
{
    public void Handle(ChangedEvent args)
    {

    }
}

然后我可以在我的程序集中发现IHandler<>的所有具体实现,我想这样做:

I can then discover all concrete implementations of IHandler<> in my assemblies, and I wanted to do something like this:

IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
    object instance = Activator.CreateInstance(type);
    Listeners.Register((IHandler<IEvent>)instance);
}

代码将编译,它不是无效的,但在运行时,因为它无效。
然而,如果我转换到一个具体的IEvent像:

The code will compile, it's not invalid, but in run time the cast fails because it's invalid. However, if I cast to a concrete IEvent like:

IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
    object instance = Activator.CreateInstance(type);
    Listeners.Register((IHandler<ChangedEvent>)instance);
}

此强制转换有效,它将运行。问题是场景的动态,我想要能够发现类型并注册它们。
我不想为处理程序创建一个非通用接口,但我相信这是一个不可能的情况,因为框架没有足够的信息来推断所需的类型。
有没有办法实现这一点,或者你有任何建议,以实现期望的结果?

This cast is valid, and it will run. The problem is the dynamic of the scenario, I want to be able to discover the types and register them. I didn't want to create a non-generic interface for the handler, but I believe this is an impossible scenario because the framework doesn't have enough information to infer the required types. Is there any way to achieve this, or do you have any sugestions to achieve the desired result?

非常感谢。

推荐答案

这不起作用,因为协方差和逆变,想象这个工作,你做了以下。

This doesn't work because of Covariance and contravariance, imagine this worked and you did the following.

public class AnotherTypeOfEvent : IEvent      {...} 

public void Register<TEvent>(IHandler<TEvent> handler) where TEvent : IEvent 
{
    //Really our runtime type expects ChangedEvent, but our constraint is
    //only for IEvent so you could do this - oh dear..
    handler.Handle(new AnotherTypeOfEvent());     
}

Listeners.Register((IHandler<IEvent>)new ChangedHandler());   

您会将 AnotherTypeOfEvent code> ChangedHandler.Handle 方法,它清楚地预期 ChangedEvent ,这将导致各种问题。

You would be passing AnotherTypeOfEvent into you ChangedHandler.Handle method, which clearly expects ChangedEvent, this would cause all sorts of problems.

这篇关于动态通用接口转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆