【问题标题】:Type error in command pattern命令模式中的类型错误
【发布时间】:2018-02-23 15:52:12
【问题描述】:

我正在尝试为命令本身实现具有强类型输入和输出参数的命令模式。

首先我创建了两个接口来标记命令的输入和输出:

interface IRequest { }
interface IResponse { }

然后我创建了基类和接口。这是抽象接收器

interface IReceiver<TRequest, TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    TResponse Action( TRequest request );
}

这是抽象命令

abstract class AbstractCommand<TRequest, TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    protected IReceiver<TRequest, TResponse> _receiver;

    public AbstractCommand( IReceiver<TRequest, TResponse> receiver ) {
        _receiver = receiver;
    }

    public abstract TResponse Execute( TRequest request );
}

现在我正在尝试使用这些对象,因此我创建了所需的具体类

class TypeARequest : IRequest
{
    public TypeARequest() {
    }

    public int NumericValueA { get; set; }
    public int NumericValueB { get; set; }
}

class TypeAResponse : IResponse
{
    public TypeAResponse() {
    }

    public int Result { get; set; }
}

class SumCommand : AbstractCommand<TypeARequest, TypeAResponse>
{
    public SumCommand( IReceiver<TypeARequest, TypeAResponse> receiver ) : base( receiver ) {
    }

    public override TypeAResponse Execute( TypeARequest request ) {
        return _receiver.Action( request );
    }
}

class SumReceiver : IReceiver<TypeARequest, TypeAResponse>
{
    public TypeAResponse Action( TypeARequest request ) {
        return new TypeAResponse() { Result = request.NumericValueA + request.NumericValueB };
    }

}

最后我创建了一个 CommandProcessor 类,它应该能够同时处理多个命令

class CommandProcessor
{
    IList<AbstractCommand<IRequest, IResponse>> _supportedCommands = new List<AbstractCommand<IRequest, IResponse>>();

    public CommandProcessor() {
    }

    void AddSupportedCommand( AbstractCommand<IRequest, IResponse> item ) {
        _supportedCommands.Add( item );
    }

    void SetupSupportedCommands() {
        // ERROR HERE 
        AddSupportedCommand( new SumCommand( new SumReceiver() ) );
    }

}

但是我得到一个编译时错误说:

参数 1:无法从“SumCommand”转换为 '抽象命令'

有什么帮助或建议吗?

【问题讨论】:

标签: c# command-pattern


【解决方案1】:

您应该创建一个接口并将您的泛型参数标记为协方差示例:

interface IRequest { }
interface IResponse { }
interface IReceiver<in TRequest, out TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    TResponse Action(TRequest request);
}

interface ICommand<out TRequest, out TResponse>
{

}

abstract class AbstractCommand<TRequest, TResponse> : ICommand<TRequest, TResponse>
    where TRequest : IRequest   
    where TResponse : IResponse
{
    protected IReceiver<TRequest, TResponse> _receiver;

    public AbstractCommand(IReceiver<TRequest, TResponse> receiver)
    {
        _receiver = receiver;
    }

    public abstract TResponse Execute(TRequest request);
}

class CommandProcessor
{
    IList<ICommand<IRequest, IResponse>> _supportedCommands = new List<ICommand<IRequest, IResponse>>();

    public CommandProcessor()
    {
    }

    void AddSupportedCommand(ICommand<IRequest, IResponse> item)
    {
        _supportedCommands.Add(item);
    }

    void SetupSupportedCommands()
    {
        AddSupportedCommand(new SumCommand(new SumReceiver()));
    }

}

更多信息在这里out modifier msdn

【讨论】:

  • 谢谢。实际上,您的解决方案最终会出现错误提示 Invalid variance modifier. Only interface and delegate type parameters can be specified as variant. 但是似乎可以通过创建 ICommand 接口来解决...
  • 是的,我遇到了那个错误,我正在修复它并更新我的解决方案。抱歉不是我的本意
  • 我理解不用担心。但是,在您进行编辑之后,我仍然收到错误:首先我无法将“out”添加到 IRequest,然后我也收到与以前相同的错误。如果你把我的代码放在控制台程序中,你应该会得到同样的错误
  • 在 IReciever 中,您不能将 TRequest 作为协方差添加到构造函数中,您可以将其保留为没有“out”
  • 想多次投票。我想我需要更多地了解协变和逆变:) 谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-12-16
  • 2023-03-25
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 2019-09-21
相关资源
最近更新 更多