2017-09-14 66 views
5

我正在嘗試爲命令本身實現具有強類型輸入和輸出參數的命令模式。命令模式中的類型錯誤

首先我已經創建了標記輸入和輸出該命令兩個接口:

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' 轉換爲 'AbstractCommand'

任何幫助或建議?

+2

我想這是你的陷阱:https://docs.microsoft.com/en -us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/index這也是:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/創建變體通用接口 – Fildor

回答

2

你應該創建一個接口,並將您的泛型參數的協方差例如:

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

+0

謝謝。實際上你的解決方案最後會出現一個錯誤,說'無效的變量修飾符。只有接口和委託類型參數可以指定爲變體。 \t'不過似乎可以通過創建一個'ICommand'界面來解決...... – Lorenzo

+0

是的,我遇到了這個錯誤,我修復了它並更新了我的解決方案。對不起,我的意圖不是我的意思 – Alcruz

+0

不用擔心我明白。但是,在完成編輯之後,我仍然遇到錯誤:首先,我無法將「出」添加到IRequest,然後我也得到與以前相同的錯誤。如果你把我的代碼放在一個控制檯程序中,你應該得到相同的錯誤 – Lorenzo