这是我的类的简化代码:
public class Game
{
World world;
DataManager dataManager;
public Game()
{
world = new World();
dataManager = new DataManager();
}
public void Run()
{
Menu mainMenu = new Menu(dataManager,world);
//world = dataManager.LoadFile("Games\test game.xml");
//the commented line above is correcting my bug but I don't want
//to do it that way.
List <Location> locs = world.GetAllLocations();
//when the debug mode arrives at this point, world is empty.
}
}
public class Menu
{
DataManager dataManager ;
World world;
public Menu(DataManager _dataManager, World _world)
{
this.dataManager = _dataManager;
this.world = _world;
world = dataManager.LoadFile("Games\test game.xml");
//the world is filled correctly here above.
}
}
这两个类共享相同的命名空间。 我的数据管理器用一个XML填充世界,它完美地工作。 世界应该是 game.world 属性的参考,但一旦我们回到游戏类中,它似乎就变得空了......
我真的不明白程序的行为方式。 如果您需要更多,这里是完整的来源:
https://github.com/mikyjax/TextAdventureGameEditor/tree/master/Text%20Adventure%20Engine
这不是引用的工作方式。
new Menu(dataManager,world);
<= 调用构造函数并传入在构造函数中创建的world
实例(这与传入引用不同)。this.world = dataManager.LoadFile("Games\test game.xml")
<= 创建一个新实例(因此是新指针)并分配给局部变量world
。没有发生的是run
中的调用方法现在共享相同的world
实例,该实例仍然是null
。
如果这是您想要的,则必须使用 ref 关键字(或out
)。
public Menu(DataManager _dataManager, ref World _world)
并调用它
new Menu(dataManager,ref world);
也就是说,这是两个层面上的不良做法。
- 构造函数中不应有副作用
- 如果要创建一个对象以在对象外部使用(例如在工厂中),则应为此使用专用方法,然后将该对象作为方法的返回返回。
public class Menu {
DataManager dataManager ;
World world;
public Menu(DataManager _dataManager)
{
this.dataManager = _dataManager;
}
public World CreateWorld() {
if(this.world == null)
this.world = dataManager.LoadFile("Games\test game.xml");
return this.world;
}
}
public class Game {
World world;
public void Run()
{
Menu mainMenu = new Menu(dataManager);
this.world = mainMenu.CreateWorld();
}
}
你的代码类似于:
A = B
A = C
然后你想知道为什么B
不C
:你设置Menu.World = _world
,然后重写Menu.Wold
为从XML加载的内容:_world
不受它修改。
为什么Menu
构造函数来填充世界 - 这不是它的唯一责任 - 是吗?
我会将您的静态LoadFile
重命名为CreateWorld(..filename..)
,并在创建 Menu之前在Run
方法中调用它。这样,您就可以将准备好的World
提供给 Menu 构造函数。
我仍然想知道的是,为什么菜单需要访问您的原始世界数据......