C# 两个物体相互需要

C# 两个物体相互需要,c#,C#,基本上我有三个类:Game、Level和Player(这是一个GameObject)。剥离到最低限度,它看起来像这样: class Game { private Level[] levels; private Player player; public Game() { levels = new []{new Level(player)}; player = new Player(levels[0]); } } clas

基本上我有三个类:
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 {}
class Level
{
    private Game game;

    public Level(Game game)
    {
        this.game = game;
    }
}

class Player
{
    private Game game;

    public Player(Game game)
    {
        this.game = game;
    }
}
levels = { new Level(this) } // (this refers to the instance of Game)
player = new Player(this);
类游戏
{
私人层面[]层面;
私人玩家;
公共游戏()
{
等级=新[]{新等级(玩家)};
玩家=新玩家(等级[0]);
}
}
班级
{
私有列表游戏对象;
公共级别(玩家)
{
游戏对象。添加(玩家);
}
公共void DoSomething(){}
}
玩家类别:游戏对象
{
私人层面;
公共玩家(级别)
{
这个水平=水平;
level.DoSomething();
}
}
抽象类GameObject{}

有可能以某种方式使这项工作成功吗<代码>玩家必须在
游戏
中创建

修复您的设计。在两个方向(或至少两个方向)上,玩家和关卡之间都没有“has-a”关系。或者如果你认为有,解释你为什么这么认为

正如您所发现的,使用您当前的设计,您无法实例化一个而不实例化另一个,从而创建循环依赖关系。当然,要“让它工作”,您可以创建一个属性或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;

如前所述,如果没有另一个对象,就不能实例化一个对象。如果您想保留现在的设计,解决方案是在每个类中都有一个
Game
引用,如下所示:

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 {}
class Level
{
    private Game game;

    public Level(Game game)
    {
        this.game = game;
    }
}

class Player
{
    private Game game;

    public Player(Game game)
    {
        this.game = game;
    }
}
levels = { new Level(this) } // (this refers to the instance of Game)
player = new Player(this);
您可以在Game类中这样构造它们:

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 {}
class Level
{
    private Game game;

    public Level(Game game)
    {
        this.game = game;
    }
}

class Player
{
    private Game game;

    public Player(Game game)
    {
        this.game = game;
    }
}
levels = { new Level(this) } // (this refers to the instance of Game)
player = new Player(this);
由于构造函数接受
游戏的一个实例

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

this.game.levels


好吧,下次在你的问题上加上
Unity
标签。 现在它不起作用了,因为当前的
Player
类需要
Level
类的实例(在构造函数中),而
Level
类需要
Player
类的实例-这造成了循环依赖,两个对象都不能实例化。因此,首先我们应该通过将
Player
删除到
级别
聚合来打破它。由于我们有一个条件(
Player
必须仅在
Game
类中实例化),我们应该将其标记为
abstract

abstract class AbstractPlayer : GameObject
{
    public Level level { get; set; }
}
现在我们可以用新逻辑修改
Game
类,并添加从
AbstractPlayer
继承的嵌套具体
Player
类:

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() {}
}
类游戏
{
私人名单级别;
私人玩家;
公共游戏()
{
player=新玩家();
关卡。添加(玩家);
}
//如果需要,请取消对该方法的注释
//公共播放器CreatePlayer()
//{
//返回新玩家();
//}
私有类玩家:AbstractPlayer
{
公共玩家()
{
}            
}
}
班级
{
私有列表游戏对象;
公共级别(玩家)
{
游戏对象。添加(玩家);
player.Level=这个;
}
公共void DoSomething(){}
}

我们已经准备好了!你的问题是什么?“让它发挥作用”可能意味着许多不同的事情?当你认为你的代码在工作时?@ StAXX我的目标是用相同的<代码>播放器实例创建<代码>级别>代码> s,并能够从<代码>播放器< /代码>中调用<代码>级别。