Q:

Automatically update one-to-many bi-directional relationship

In an example game engine server, the game world could be represented by a World object. The game might have multiple game worlds and a player who is in a world only needs to receive position data of units in that world.
class World
{
    public List<Unit> Units { get; set; }
}

However a piece of code also needs to be able to look up what world a unit is in easily, so the unit object itself keeps track of a world reference.
class Unit
{
    public World World { get; set; }
}

This works for lookup, but quickly becomes problematic when changing data when the programmer isn't aware of the relationship between objects going on, so I changed Units in World to be readonly and have the following code in Unit.
public virtual World World
{
    get { return _world; }
    set
    {
        // 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);
    }
}

This works, but it feels like there's a better way to do this. Especially as I add more stuff that needs to be linked the same way (a World also has Structures and Players, and Structures maintain a list of Units as well), a lot of repeated functionality comes in. As well when I remove a unit from the game, it continues to be kept alive by this, so I have to remember to set the unit's structure to null every time (which I already forgot multiple times, resulting in weird bugs). Is there a better way to achieve this one-to-many relationship without manually updating both sides?

A:

The best way to accomplish this is to have each World, Structure, and anywhere else a unit can move to inherit an interface IEnterable, which looks like
public interface IEnterable
{
    void Enter(Unit unit);
    void Leave(Unit unit);
}

Your unit would then have this as a property, and a MoveTo(IEnterable location) method
public class Unit
{
     // ...

     public IEnterable CurrentLocation { get; set; }

     // ...

     public void MoveTo(IEnterable location)
     {
         if (CurrentLocation != null)
         {
              CurrentLocation.Leave(this);
         }

         location.Enter(this);
     }
}

The Enter and Leave would handle all the logic for the Unit movement.
If you wanted to get more fancy, you could have a Movement class that could describe the movement a little more accurately.
public class Movement
{
     private readonly IEnterable _destination;

     public Movement(IEnterable destination)
     {
         if (destination== null) throw new ArgumentNullException("destination"); 

         _destination = destination;
     }

     public MoveResult MoveUnit(Unit unit)
     {
         if (unit == null) throw new ArgumentNullException("unit");

         var currentLocation = unit.CurrentLocation;
         if (currentLocation  == _destination) return MoveResult.SameLocation;

         if (!IsValidMove(currentLocation, _destination) return MoveResult.InvalidMovment;

         currentLocation.Leave(unit);

         _destination.Enter(unit);
     }
}

This will get the movement logic out of the Unit class because a unit should not care about how it has to move, just that it has.
I might be missing something, but my main point is to use an interface for each object that a Unit can enter, and the ease of moving a Unit becomes much better.

