【问题标题】:Extract inherited class argument from constructor从构造函数中提取继承的类参数
【发布时间】:2023-03-14 19:49:01
【问题描述】:

首先抱歉,如果我会使用混乱的术语,我仍在学习很多关于命令模式和 C# 的知识。

我正在尝试使用 C# 在 Unity3D 中实现命令模式,特别是 this implementation 适合我的情况。

鉴于Command.csGameController.cs 脚本,我创建了一个DoThing 类,继承自Command 类,使用以下代码实现:

public class DoThing : Command
{
    public string name;
    public int healthPoints;

    public DoThing(string name, int healthPoints)
    {
        this.name = name;
        this.healthPoints = healthPoints;
    }
}

现在,由于我通过构造函数(namehealthPoints)将一些参数传递给命令,我想从另一个脚本中提取这些参数。

我尝试(成功)将参数传递给以下行中的命令并将命令保存在堆栈中:

var doCommand = new DoThing("asdf", 123);
Stack<Command> listOfCommands = new Stack<Command>();
listOfCommands.Push(doCommand);

我尝试(成功)在代码执行期间在监视窗口中检索这些参数:

listOfCommands.Peek().name //returns "asdf"

但是这在脚本中不起作用,这意味着看不到参数:

Debug.Log(listOfCommands.Peek().name) //throws error

有没有办法提取参数?

【问题讨论】:

    标签: c# unity3d command command-pattern


    【解决方案1】:

    由于您的listOfCommandsCommandStacklistOfCommands.Peek() 返回一个Command,它没有name 变量。在访问变量之前,您必须检查函数返回的变量的类型并对其进行强制转换。

    Command command = listOfCommands.Peek();
    if(command is DoThing)
    {
        Debug.Log(((DoThing) command).name);
    }
    

    或更紧凑

    if(listOfCommands.Peek() is DoThing doThing)
    {
        Debug.Log(doThing.name);
    }
    

    DoThing doThing = listOfCommands.Peek() as DoThing;
    if(doThing != null)
    {
        Debug.Log(doThing.name);
    }
    

    【讨论】:

      【解决方案2】:

      来自Command pattern维基:

      命令对象知道接收者并调用接收者的方法。接收器方法的参数值存储在 命令。执行这些方法的接收器对象也被存储 通过聚合在命令对象中。然后接收器完成工作 当调用命令中的 execute() 方法时。 调用者对象 知道如何执行命令,并且可以选择记账 命令执行。调用者不知道任何关于 具体命令,它只知道命令接口。

      因此,如果DoThing 命令的作用是将消息记录到控制台,它应该如下所示:

      public abstract class Command
      {
          public abstract void Execute();        
      }
      
      public class DoThing : Command
      {
          public string name;
          public int healthPoints;
      
          public DoThing(string name, int healthPoints)
          {
              this.name = name;
              this.healthPoints = healthPoints;
          }
          public override void Execute(){
              Debug.Log(name);
              // whatever else the command does
          }
      }
      

      你会在命令上调用执行。

      【讨论】:

        猜你喜欢
        • 2015-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-08
        • 1970-01-01
        • 2019-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多