问题描述
首先,很抱歉,如果我要使用混乱的术语,我仍在学习有关Command模式和C#的很多知识。
我正在尝试使用C#在Unity3D中实现命令模式,特别是this implementation重新适应了我的情况。
鉴于Command.cs和GameController.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;
}
}
现在,由于我通过构造函数(name
,healthPoints
)向Commands传递了一些参数,所以我想从另一个脚本中提取这些参数。
我试图(成功地)将参数传递给以下行中的命令并将该命令保存在堆栈中:
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
解决方法
由于您的listOfCommands
是Stack
的{{1}},所以Command
返回的listOfCommands.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);
}
,
来自Command pattern Wiki:
命令对象了解接收方并调用接收方的方法。接收器方法的参数值存储在 命令。执行这些方法的接收者对象也被存储 在命令对象中通过聚集。然后,接收者完成工作 当命令中的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
}
}
然后您将在命令上调用execute。