首页 > 解决方案 > C# 实现不可分配给接口

问题描述

所以我得到了以下接口:

public interface ICommand<TResult> { }
internal interface ICommandHandler<in TCommand, out TResult> where TCommand : ICommand<TResult> {
    TResult Handle(TCommand command);
}

和以下命令:

public sealed class DisconnectCommand : ICommand<bool> { }
internal sealed class DisconnectCommandHandler : ICommandHandler<DisconnectCommand, bool> {
    bool Handle(DisconnectCommand command) => true
}

现在,在我的代码中某处,在我的所有命令处理程序的外观中,我有以下函数,其中我有我所有的命令处理程序可供我使用,并且我能够通过反射找到正确的处理程序:

public TResult HandleCommand<TResult>(ICommand<TResult> command);

问题是,我不能将任何命令处理程序分配给接口类型的变量

ICommandHandler<ICommandy<TResult>, TResult> selectedHandler = ...;

即使我特别尝试执行以下操作,编译器也会告诉我他不能将 DisconnectedCommandHandler 类型分配给 ICommandHandler:

ICommandHandler<ICommand<bool>, bool> testHandler = new DisconnectCommandHandler();

我怀疑它与使用 DisconnectCommand 作为 ICommandHandler 而不是 ICommand 的通用参数有关,但我想明确设置它,因为可能会发生中间有几层抽象类的情况。解决这个问题的正确方法是什么?

标签: c#generics

解决方案


听起来您正在尝试创建一个命令处理器来将所有命令分派给正确的处理程序。您无法尝试将生成的命令处理程序分配给接口,但您可以使用dynamic,并且由于您的命令处理程序只有一个Handle方法,您可以确定使用该方法将始终有效。有关完整示例,您可以查看此博客文章,该文章解释了如何执行您正在尝试的操作。仅供参考,QueryProcessor来自该帖子。

sealed class QueryProcessor : IQueryProcessor
{
    private readonly Container container;

    public QueryProcessor(Container container)
    {
        this.container = container;
    }

    [DebuggerStepThrough]
    public TResult Process<TResult>(IQuery<TResult> query)
    {
        var handlerType = typeof(IQueryHandler<,>)
            .MakeGenericType(query.GetType(), typeof(TResult));

        dynamic handler = container.GetInstance(handlerType);

        return handler.Handle((dynamic)query);
    }
}

此外,如果您尝试实现某种 CQRS,那么您所称的 aCommand应该被称为 a Query,因为您正在返回一个结果。


推荐阅读