C# 对象丢失其引用并变为空

  • 本文关键字:引用 对象 c# object null
  • 更新时间 :
  • 英文 :


这是我的类的简化代码:

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

这不是引用的工作方式。

  1. new Menu(dataManager,world);<= 调用构造函数并传入在构造函数中创建的world实例(这与传入引用不同)。
  2. 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);

也就是说,这是两个层面上的不良做法。

  1. 构造函数中不应有副作用
  2. 如果要创建一个对象以在对象外部使用(例如在工厂中),则应为此使用专用方法,然后将该对象作为方法的返回返回。

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

然后你想知道为什么BC:你设置Menu.World = _world,然后重写Menu.Wold为从XML加载的内容:_world不受它修改。

为什么Menu构造函数来填充世界 - 这不是它的唯一责任 - 是吗?

我会将您的静态LoadFile重命名为CreateWorld(..filename..),并在创建 Menu之前在Run方法中调用它。这样,您就可以将准备好的World提供给 Menu 构造函数。

我仍然想知道的是,为什么菜单需要访问您的原始世界数据......

相关内容

  • 没有找到相关文章

最新更新