C# 命令设计模式-带返回值的执行方法

C# 命令设计模式-带返回值的执行方法,c#,design-patterns,C#,Design Patterns,我已经根据下面的UML实现了命令设计模式 其中Command是一个名为ICommand的接口: public interface ICommand { CommandType CommandType { get; set; } Task Execute(); } 这是一个完美的设计,直到我被要求从Task Execute()返回值

我已经根据下面的UML实现了命令设计模式

其中Command是一个名为ICommand的接口:

 public interface ICommand
    {
        CommandType CommandType { get; set; }
        Task  Execute();
    }
这是一个完美的设计,直到我被要求从
Task Execute()返回值Task Execute();
”,但这意味着我需要向实现
ICommand
接口的所有类(大约10个类)添加空实现

我希望ConcreteCommand将只有一个
Execute
方法,可以吗? 对于每个具体的命令,它必须对其他方法有空的实现吗? 有没有办法将这些方法组合成一个使用任务

为了澄清,我不想有两种方法:

 public interface ICommand
    {
        CommandType CommandType { get; set; }
        Task  Execute();
        Task<T> Execute<T>();
    }
公共接口ICommand
{
CommandType CommandType{get;set;}
任务执行();
任务执行();
}

谢谢

由于调用程序可以在运行时更改命令,因此必须具有松散类型安全性。对于知道命令返回值的情况,可以将其返回类型传递给execute():


谢谢你的回答!仍然想知道没有返回值的具体命令是什么?doAction会是什么样子?因为doAction()返回一个对象,所以它必须返回一个值;对void命令使用伪值,例如
true
。(增加示例)
using System;

class Receiver {
    public bool someAction() {
        return false;
    }
    
    public string someAction2() {
        return "some action value";
    }

    public void voidAction() {
        Console.WriteLine("void action");
    }
}

interface ICommand {
    object doAction();
};

class ConcreteCommand : ICommand {
    private Receiver receiver;
    
    public ConcreteCommand(Receiver recv) {
        receiver = recv;
    }
    
    public object doAction() {
        return receiver.someAction();
    }
}

class ConcreteCommand2 : ICommand {
    private Receiver receiver;
    
    public ConcreteCommand2(Receiver recv) {
        receiver = recv;
    }
    
    public object doAction() {
        return receiver.someAction2();
    }
}

class VoidCommand : ICommand {
    private Receiver receiver;
    
    public VoidCommand(Receiver recv) {
        receiver = recv;
    }
    
    public object doAction() {
        receiver.voidAction();
        return true;
    }
}

class Invoker {
    private ICommand command;
    
    public void setCommand(ICommand cmd) {
        command = cmd;
    }
    
    public T execute<T>() {
        return (T) command.doAction();
    }
}

public class Program
{
    public static void Main()
    {
        Invoker i = new Invoker();
        Receiver r = new Receiver();
        
        i.setCommand(new ConcreteCommand(r));
        Console.WriteLine(i.execute<bool>());
        
        i.setCommand(new ConcreteCommand2(r));
        Console.WriteLine(i.execute<string>());
        
        i.setCommand(new VoidCommand(r));
        i.execute<object>();

        ICommand[] commands = new ICommand[] {
            new ConcreteCommand(r),
            new ConcreteCommand(r),
            new ConcreteCommand2(r),
            new ConcreteCommand2(r),
            new VoidCommand(r)
        };
        
        foreach (ICommand c in commands) {
            i.setCommand(c);
            Console.WriteLine(i.execute<object>());
        }
    }
}
False
some action value
void action
False
False
some action value
some action value
void action
True