首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混凝土子类通用工厂

混凝土子类通用工厂
EN

Stack Overflow用户
提问于 2017-05-23 13:47:04
回答 2查看 178关注 0票数 1

考虑以下代码:

代码语言:javascript
复制
public interface IEventHandler<in T> where T : IEvent
{
    void Execute(T @event);
}

对于这些处理程序,我实现了一些具体的处理程序子类:

代码语言:javascript
复制
public class SomeEventHandler : IEventHandler<SomeEvent>
{
    public void Execute(SomeEvent @event) { /* ... */ }
}

现在我有了一个工厂来检索事件的相应处理程序:

代码语言:javascript
复制
public class EventHandlerFactory : IEventHandlerFactory
{
    public IEventHandler<T> Create<T>(T @event) where T : IEvent
    {
        // What to do in here?
    }
}

我试图检查事件的类型,然后返回相应的处理程序,但是类型系统当然拒绝这样做:

代码语言:javascript
复制
if(@event is SomeEvent)
{
    return (IEventHandler<T>) new SomeEventHandler();
}

我不会这么做,但我想知道如何允许代码使与Create<T>的接口成为可能。

编辑:当我循环遍历事件枚举时,T被视为IEvent,所以类型系统将抛出一个异常:

代码语言:javascript
复制
var events = IEnumarable<IEvent>() { /* ... */ };

foreach (var @event in events)
{
    var eventHandler = eventHandlerFactory.Create(@event);
}

Create(T @event)-method将抛出一个异常,因为T是一个IEvent而不是具体类型。我可以用(dynamic) @event来解决这个问题,但这不是我真正想要做的。

EN

回答 2

Stack Overflow用户

发布于 2017-05-23 14:03:52

经典的工厂模式。

我喜欢为这样的事情做以下事情:

代码语言:javascript
复制
public class EventHandlerFactory : IEventHandlerFactory
{
    private readonly Dictionary<Type, Type> _eventHandlers = new Dictionary<Type, Type>();

    public EventHandlerFactory()
    {
        //add a mapping between the type, and the handler
        //note - this could be done with reflection to automate this
        _eventHandlers.Add(typeof(SomeEvent), typeof(SomeEventHandler));
    }

    public IEventHandler<T> Create<T>(T @event) where T : IEvent
    {
        var handler = _eventHandlers[typeof(T)];

        if (handler != null)
        {
            //now use Activator.CreateInstance to instantiate the type
            return (IEventHandler<T>)Activator.CreateInstance(handler);
        }

        throw new Exception("Handler not found");
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-05-23 14:26:46

备选解决办法:

如果您希望避免反射,或者您的IEventHandler实现没有默认构造函数:

代码语言:javascript
复制
public interface IEventHandler
{
}

public interface IEventHandler<in T> : IEventHandler where T : IEvent
{
    void Execute(T @event);
}

public class EventHandlerFactory
{
    private static readonly Dictionary<Type, Func<IEventHandler>> _eventHandlers = new Dictionary<Type, Func<IEventHandler>>
    {
        { typeof(SomeEvent), () => new SomeEventHandler() }
    };

    public IEventHandler<T> Create<T>(T @event) where T : IEvent
    {
        Func<IEventHandler> handler;
        if (_eventHandlers.TryGetValue(typeof(T), out handler))
        {
            return (IEventHandler<T>)handler();
        }

        throw new Exception("Handler not found");
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44136682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档