两个物体需要彼此

时间:2015-10-10 14:48:48

标签: c#

基本上我有3个班级:GameLevelPlayerGameObject)。剥离到最低限度它看起来像这样:

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

3 个答案:

答案 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

的实例

然后,要访问关卡或玩家对象,您可以在LevelPlayer内执行此操作:

this.game.levels

this.game.player

答案 2 :(得分:0)

好吧,下次在您的问题中添加Unity标记。 因为它现在不起作用,因为当前Player类需要Level类的实例(在构造函数中)而Level类需要Player类的实例 - 这使得循环依赖,两个对象都不能实例化。首先,我们应该通过删除PlayerLevel聚合来打破它。由于条件(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() {}
}