Costumo usar essa abordagem em meu próprio jogo C # /. NET. Além dos outros benefícios (e riscos!) Descritos aqui, também pode ajudar a evitar problemas de serialização.
Se você deseja aproveitar os recursos internos de serialização binária do .NET Framework, o uso de IDs de entidade pode ajudar a minimizar o tamanho do gráfico de objeto gravado. Por padrão, o formatador binário do .NET serializa um gráfico inteiro de objetos no nível do campo. Digamos que eu queira serializar uma Ship
instância. Se Ship
houver um _owner
campo referenciando Player
quem é o proprietário, essa Player
instância também será serializada. Se Player
contiver um _ships
campo (de, digamos ICollection<Ship>
), todos os navios do jogador também serão gravados, juntamente com outros objetos referenciados no nível do campo (recursivamente). É fácil serializar acidentalmente um grande gráfico de objetos quando você deseja serializar apenas uma pequena parte dele.
Se, em vez disso, tenho um _ownerId
campo, posso usar esse valor para resolver a Player
referência sob demanda. Minha API pública pode até permanecer inalterada, com a Owner
propriedade simplesmente executando a pesquisa.
Embora as pesquisas baseadas em hash sejam geralmente muito rápidas, a sobrecarga adicional pode se tornar um problema para conjuntos de entidades muito grandes com pesquisas frequentes. Se isso se tornar um problema para você, você poderá armazenar em cache a referência usando um campo que não seja serializado. Por exemplo, você poderia fazer algo assim:
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();
}
}
Claro, essa abordagem também pode fazer a serialização mais difícil quando você realmente quer para serializar um gráfico de objeto grande. Nesses casos, você precisaria criar algum tipo de 'contêiner' para garantir que todos os objetos necessários sejam incluídos.