Uso spesso questo approccio nel mio gioco C # /. NET. A parte gli altri vantaggi (e pericoli!) Descritti qui, può anche aiutare a evitare problemi di serializzazione.
Se si desidera sfruttare le funzionalità di serializzazione binaria integrate in .NET Framework, l'utilizzo degli ID entità può aiutare a ridurre al minimo le dimensioni del grafico a oggetti che viene scritto. Per impostazione predefinita, il formattatore binario di .NET serializzerà un intero oggetto grafico a livello di campo. Diciamo che voglio serializzare Ship
un'istanza. Se Ship
ha un _owner
campo che fa riferimento a Player
chi lo possiede, anche Player
quell'istanza verrebbe serializzata. Se Player
contiene un _ships
campo (di, diciamo, ICollection<Ship>
), anche tutte le navi del giocatore verranno scritte, insieme a qualsiasi altro oggetto a cui si fa riferimento a livello di campo (ricorsivamente). È facile serializzare accidentalmente un enorme oggetto grafico quando si desidera serializzare solo una piccola parte di esso.
Se, invece, ho un _ownerId
campo, allora posso usare quel valore per risolvere il Player
riferimento su richiesta. La mia API pubblica può anche rimanere invariata, con la Owner
proprietà che esegue semplicemente la ricerca.
Mentre le ricerche basate sull'hash sono generalmente molto veloci, l'overhead aggiunto potrebbe diventare un problema per gruppi di entità molto grandi con ricerche frequenti. Se diventa un problema per te, puoi memorizzare nella cache il riferimento usando un campo che non viene serializzato. Ad esempio, potresti fare qualcosa del genere:
public class Ship
{
private int _ownerId;
[NonSerialized] private Lazy<Player> _owner;
public Player Owner
{
get { return _owner.Value; }
}
public Ship(Player owner)
{
_ownerId = owner.PlayerID;
EnsureCache();
}
private void EnsureCache()
{
if (_owner == null)
_owner = new Lazy<Player>(() => Game.Current.Players[_ownerId]);
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
EnsureCache();
}
}
Naturalmente, questo approccio può anche rendere più difficile la serializzazione quando si desidera effettivamente serializzare un grafico di oggetti di grandi dimensioni. In questi casi, è necessario escogitare una sorta di "contenitore" per assicurarsi che siano inclusi tutti gli oggetti necessari.