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,并能够从<代码>播放器< /代码>中调用<代码>级别。