我现在一直试图解决这个问题很长时间(3天),我只是想不通.我将尝试全面解释这个问题,因为它有点复杂.
我的学校任务是在C#Visual Studio 2008中使用OOP创建一个简单的文本游戏(应该建立在教师为我们提供的库上).它应该只使用控制台.我在使用PHP和C++的OOP方面有很好的经验,但我仍然无法理解这一点.
80%的文字游戏已经开始工作了,所以我不会厌倦你的课程和已经有效且与问题无关的东西.好的,我们开始吧:
游戏中的每个命令(你可以输入到控制台并点击回车)都由一个类表示,它既扩展了抽象类,又从我应该构建游戏的库中扩展了一个接口.Bellow是一个类Use用于表示使用项目的命令(例如,您在控制台中输入"use sword",游戏将查找名为sword的项目并调用其使用方法):
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Game.Commands { class Use : TextGame.Commands.ACommand, TextGame.Commands.ICommand { private string name; public new string Name { set { this.name = value; } get { return this.name; } } private string description; public new string Description { set { this.description = value; } get { return this.description; } } private string parameters; public new string Params { set { this.parameters = value; } get { return this.parameters; } } public Use(string name, string description) : base(name, description) { this.name = name; this.description = description; } private TextGame.Core.GameState gameState; public TextGame.Core.GameState Execute(TextGame.Core.IGame game) { // This is just a test because it appears the problem is // with the parameters property. There should be a command // you have typed in the console but its always null // Note that I have not yet coded the body of this method. // I will do that once I solve the problem. if (this.parameters == null) { Console.WriteLine("is null"); } else { Console.WriteLine(this.parameters); } return this.gameState; } } }
还有两个使用的类.Parser类和Game类.还有一段时间,所以我只会发布相关内容的片段.解析器类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; // ArrayList, Dictionary, Hashtable using System.Text.RegularExpressions; // regex engine using Game.Commands; namespace Game { class Parser { private ArrayList commands = new ArrayList(); // All commands that are available in the game so far are // initialized here in the constructor (and added to the arraylist)... // skip to the other method this is not important public Parser() { this.commands.Add(new North("^north", "Go north")); this.commands.Add(new South("^south", "Go south")); this.commands.Add(new East("^east", "Go east")); this.commands.Add(new West("^west", "Go west")); this.commands.Add(new Use("^use\\s\\w+", "Try to use the selected item")); this.commands.Add(new Quit("^quit", "Quit the game")); } // This method takes as an argument a string representing // a command you type in the console. It then searches the arraylist // via the regex. If the command exists, it returns an the command object // from the arraylist // This works fine and returns right objects (tested) public TextGame.Commands.ACommand GetCommand(string command) { TextGame.Commands.ACommand ret = null; foreach (TextGame.Commands.ACommand c in this.commands) { Regex exp = new Regex(@c.Name, RegexOptions.IgnoreCase); MatchCollection MatchList = exp.Matches(command); if (MatchList.Count > 0) { ret = c; } } return ret; } } }
现在是Game类的一个片段,我在上面使用了两个类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using TextGame.Core; using System.Collections; using Game.Items; using Game.Commands; namespace Game { class Game : TextGame.Core.IGame { public void Play() { // Here I read commands from the console in a loop and // call the ProcessCommand() method. No problem here. while (true) { string command = Console.ReadLine(); this.ProcessCommand(command); } } // This is the IMPORTANT method so take a closer look private TextGame.Core.GameState gameState; public TextGame.Core.GameState ProcessCommand(string command) { Parser parser = new Parser(); TextGame.Commands.ACommand c = parser.GetCommand(command); if (c != null) { // HERE I ADD THE COMMAND FROM THE CONSOLE TO THE C OBJECT // I ADD IT VIA THE SETTER TO THE PARAMETERS PROPERTY // OF THE COMMAND c.Params = command; // AND I CALL THE COMMAND'S EXECUTE() METHOD - SEE THE FIRST CLASS - // USE - WHERE I TEST FOR THE PARAMS PROPERTY BUT IT IS STILL NULL this.gameState = ((TextGame.Commands.ICommand)c).Execute(this); } } } }
我在片段中添加了注释来描述问题所在.我希望我已经解释得很好.
有人有什么想法吗?我已经在这个项目上工作了大约3个星期,大部分时间都很顺利,3天前我遇到了这个问题,从那以后我一直试图解决这个问题.
您的问题是'new'关键字.这是您在"使用"类中使用它的位置:
private string parameters; public new string Params { set { this.parameters = value; } get { return this.parameters; } }
您正在创建一个不同的属性,恰好与您继承的类型上的属性具有相同的名称.'new'关键字告诉编译器你打算这样做.
基本上,这意味着如果您执行以下操作:
var x = new Use(); x.Params = "abcd"; ((ACommand)x).Params = "wxyz"; Console.Writeline("direct: " + x.Params); Console.Writeline("ACommand: " + ((ACommand)x).Params);
你会得到这个输出:
直接:abcd
ACommand:wxyz
您可能希望完全从Use中删除'Params'的定义,并继承ACommand中的定义.可能也来自名称和描述,但你应该能够从这里弄清楚你是否想要这个.