如何正确地在C#中自动更新一对多双向关系



在示例游戏引擎服务器中,游戏世界可以由世界对象表示。该游戏可能具有多个游戏世界,而在一个世界中只需要接收该世界单位的位置数据的玩家。

class World
{
    public List<Unit> Units { get; set; }
}

但是,一块代码还需要能够查找一个单元的世界,因此单元对象本身会跟踪世界参考。

class Unit
{
    public World World { get; set; }
}

这适用于查找,但是当程序员不了解对象之间的关系时,更改数据时很快就会变得有问题,因此我更改了World中的Units以进行阅读,并在Unit中具有以下代码。

public virtual World World
{
    get { return _world; }
    set
    {
        // Unit must always be in a world
        Contract.Requires<ArgumentNullException>(value != null);
        // If already this, don't do anything
        if (value == _world) return;
        var oldWorld = _world;
        _world = value;
        if(oldWorld != null) oldWorld.UpdateUnitEntry(this);
        _world.UpdateUnitEntry(this);
    }
}

这有效,但是感觉有一个更好的方法可以做到这一点。尤其是当我添加更多需要以相同方式链接的东西(World也具有Structure s和 Player s)时,许多重复的功能都出现了。是否有更好的方法可以实现这种一对一的关系而无需手动的关系。更新双方?

在像C 这样的语言中,没有如此精巧的参考管理和GC,无论如何都有类似的循环引用的问题(例如,sharedPtr)。这也为例如游戏状态的序列化。

这使我相信可能有更好的方法来解决这个问题。例如。单位真的需要了解他们的世界吗?也许查看使您认为需要的那个代码,也许您可以以不再需要的方式更改它。

因此,也许可以实现实体管理系统,仅通过抽象ID或句柄引用您的游戏实体。在不采取行动之前,请解决ID/句柄,但没有实体将其引用对另一个实体的引用。如果您发现自己想序列化游戏的状态,这也将极大地帮助您。

否则:

您所做的并不是严格的错误或其他任何事情。如果它在工作而不是太多的痛苦,那就是这样。

最新更新