基本上我有3个班级:Game
,Level
和Player
(GameObject
)。剥离到最低限度它看起来像这样:
class Game
{
private Level[] levels;
private Player player;
public Game()
{
levels = new []{new Level(player)};
player = new Player(levels[0]);
}
}
class Level
{
private List<GameObject> gameObjects;
public Level(Player player)
{
gameObjects.Add(player);
}
public void DoSomething() {}
}
class Player : GameObject
{
private Level level;
public Player(Level level)
{
this.level = level;
level.DoSomething();
}
}
abstract class GameObject {}
是否有可能以某种方式完成这项工作?必须在player
内创建Game
。
答案 0 :(得分:1)
修复您的设计。没有&#34; has-a&#34;球员和水平之间的关系,两个方向(或至少不是两者)。或者如果您认为有,请解释为什么这么认为。
正如您所发现的那样,使用您当前的设计,您无法实现另一个设置,从而创建循环依赖。当然,要#34;让它工作&#34;你可以创建一个属性或setter方法:
pubic class Player
{
private Level _level;
public Level Level
{
get { return _level; }
set { _level = value; }
}
// Or auto-implemented property
public Level Level { get; set; }
public Player()
{
}
}
(或者相同,但是等级)。
现在你可以在不需要关卡的情况下实例化玩家:
var player = new Player();
var level = new Level(player);
player.Level = level;
答案 1 :(得分:1)
如前所述,如果没有另一个对象,则无法实例化一个对象。如果你想保留你现在的设计,那么解决方案是在每个其他类中都有一个Game
引用,如下所示:
class Level
{
private Game game;
public Level(Game game)
{
this.game = game;
}
}
class Player
{
private Game game;
public Player(Game game)
{
this.game = game;
}
}
您可以在Game类中构建它们,如下所示:
levels = { new Level(this) } // (this refers to the instance of Game)
player = new Player(this);
因为构造函数接受Game
然后,要访问关卡或玩家对象,您可以在Level
或Player
内执行此操作:
this.game.levels
或
this.game.player
答案 2 :(得分:0)
好吧,下次在您的问题中添加Unity
标记。
因为它现在不起作用,因为当前Player
类需要Level
类的实例(在构造函数中)而Level
类需要Player
类的实例 - 这使得循环依赖,两个对象都不能实例化。首先,我们应该通过删除Player
到Level
聚合来打破它。由于条件(Player
必须仅在Game
类中实例化),我们应将其标记为abstract
:
abstract class AbstractPlayer : GameObject
{
public Level level { get; set; }
}
现在我们可以使用新逻辑修改Game
类,并添加继承自Player
的嵌套具体AbstractPlayer
类:
class Game
{
private List<Level> levels;
private Player player;
public Game()
{
player = new Player();
Levels.Add(player);
}
// uncomment this method if you need it
//public Player CreatePlayer()
//{
// return new Player();
//}
private class Player : AbstractPlayer
{
public Player()
{
}
}
}
class Level
{
private List<GameObject> gameObjects;
public Level(Player player)
{
gameObjects.Add(player);
player.Level = this;
}
public void DoSomething() {}
}