2017-09-14 2 views
5

J'essaie d'implémenter un modèle de commande avec des paramètres d'entrée et de sortie fortement typés pour la commande elle-même.Erreur de type dans le modèle de commande

d'abord tout ce que j'ai créé deux interfaces qui marque l'entrée et la sortie de la commande:

interface IRequest { } 
interface IResponse { } 

J'ai créé les classes de base et les interfaces. Ceci est le récepteur abstrait

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

et ce la commande abstraite

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); 
} 

Maintenant, je suis en train d'utiliser ces objets et j'ai créé les classes concrètes nécessaires

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 }; 
    } 

} 

Enfin, je ont créé une classe CommandProcessor qui devrait être capable de traiter plusieurs commandes complètement

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())); 
    } 

} 

Cependant, je reçois une erreur de compilation en disant:

Argument 1: ne convertit pas 'SumCommand' à 'AbstractCommand'

Toute aide ou suggestion?

+2

Je suppose que cela est votre prise: https://docs.microsoft.com/en -us/dotnet/csharp/guide-de-programmation/concepts/covariance-contravariance/index et aussi: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/ create-variant-generic-interfaces – Fildor

Répondre

2

Vous devez créer une interface et marquer votre paramètre générique comme exemple de covariance:

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())); 
    } 

} 

Plus d'informations ici out modifier msdn

+0

Merci. En fait, votre solution se termine par une erreur indiquant "Modificateur de variance invalide". Seuls les paramètres de type interface et délégué peuvent être spécifiés en tant que variant. \t 'Cependant, il semble que cela peut être résolu en créant une interface ICommand ... – Lorenzo

+0

Oui, je courais à cette erreur, je le corrige et mettre à jour ma solution. désolé n'était pas mon intention – Alcruz

+0

Pas de soucis je comprends. Cependant après avoir suivi votre modification, je reçois toujours des erreurs: d'abord je ne peux pas ajouter "out" à IRequest, alors j'ai aussi la même erreur qu'avant. Si vous mettez mon code dans un programme de console, vous devriez obtenir la même erreur – Lorenzo