简体   繁体   English

通用接口的运行时强制转换

[英]Runtime Casting of Generic Interface

I have a command processing routine that needs to get a Processor object from my IOC container and call the ProcessCommand on it, the processors are concrete object implementing a generic interface: 我有一个命令处理例程,需要从IOC容器中获取一个Processor对象并在其上调用ProcessCommand,这些处理器是实现通用接口的具体对象:

public interface ICommandProcessor<in T> where T : Command
{        
    Error ProcessCommand(T command);
}

the problem I have is that when I try to retreive the processor I only have a reference to the command object via the base class (Command) so I do not know the type of T (except at runtime) 我的问题是,当我尝试撤退处理器时,我仅通过基类(Command)获得对命令对象的引用,因此我不知道T的类型(运行时除外)

I have introduced a second non-generic interface 我介绍了第二个非通用接口

public interface ICommandProcessorGeneric
{

}

public interface ICommandProcessor<in T>:ICommandProcessorGeneric where T : Command
{        
    Error ProcessCommand(T command);
}

and can retreive the processor from the IOC container as follows: 并可以按如下方式从IOC容器中撤回处理器:

 protected virtual CommandProcessingResult RecognizeAndProcessCommand<T>(T command) where T : Command
 {
    ICommandProcessor<T> commandProcessor;

    try
    {
        Debug.WriteLine(String.Format( "---- Looking for processor for type {0}", command.GetType().Name));
        var g = ServiceLocator.GetInstance<ICommandProcessorGeneric>(command.GetType().Name);                
        commandProcessor = g as ICommandProcessor<T>;  //returns null!!
        Debug.WriteLine(String.Format("---- Got Processor {0}", g.GetType().Name));
    }
    catch (Exception ex)
    {
        //handle the exception
    }
    return commandProcessor.ProcessCommand(command);
}

the problem is that commandProcessor is then null as T is Command, whereas at runtime I know that T is a derived type. 问题是commandProcessor为空,因为T是Command,而在运行时我知道T是派生类型。 the object g returned from the IOC container is the correct processorm however I cannot see how I can cast g to a type that will allow me to access the ProcessCommand method. 从IOC容器返回的对象g是正确的处理器,但是我看不到如何将g强制转换为允许我访问ProcessCommand方法的类型。

I should also point out that the call into this method has no way of determining the type of the command at compile time as the command is retreived from a database by reference only to at ID field and deserialised. 我还应该指出,对该方法的调用无法在编译时确定命令的类型,因为只能通过引用ID字段从数据库中检索命令并反序列化该命令。

I've written a blog post on this very issue . 关于这个问题,我已经写了一篇博客文章

So basically what I've done in the past is to create an abstract base class for your Command Processor along with a generic one: 因此,基本上我过去所做的就是为命令处理器创建一个抽象基类以及一个通用基类:

public abstract class CommandProcessor
{
    public abstract Error ProcessCommand(Command command);
}

public abstract class CommandProcessor<TCommand> where TCommand : Command
{
    public override Error ProcessCommand(Command command)
    {
        if (command is TCommand == false)
            throw new ArgumentException("command should be of type TCommand");

        var cast = (TCommand)command;

        return this.ProcessCommand(cast);
    }

    public abstract Error ProcessCommand(TCommand command);
}

Now you don't need to do anything special dependant of what type of Command you are using: 现在,您无需根据所使用的命令类型执行任何特殊操作:

protected virtual CommandProcessingResult RecogniseAndProccessCommand<T>
    (T command) where T : Command
{
    var commandProcessor = (CommandProcessor)ServiceLocator.GetInstance<ICommandProcessorGeneric>(typeof(T).Name);

    return commandProcessor.ProcessCommand(command);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM