Como clone profundo interconectado objetos em C #?
Pergunta
O que é a melhor maneira de profunda clone um conjunto articulado de objetos? Exemplo:
class A {
B theB; // optional
// ...
}
class B {
A theA; // optional
// ...
}
class Container {
A[] a;
B[] b;
}
A coisa óbvia a fazer é andar os objetos e clone tudo profundo quanto eu for até ela. Isso cria um problema, porém -. Se eu clonar um A
que contém um B
, e que B
é também no Container
, que B
será clonado duas vezes depois que eu clonar o Container
O próximo passo lógico é criar um Dictionary
e olhar para cima cada objeto antes de cloná-lo. Isto parece que poderia ser uma solução lento e deselegante, no entanto.
Qualquer pensamento?
Solução
A sua não é uma solução elegante com certeza, mas não é incomum para usar um dicionário (ou hashmap). Um dos benefícios é que um hashmap tem um tempo de pesquisa constante, assim que a velocidade realmente não sofrem aqui.
Outras dicas
A solução dicionário que você sugerido é o melhor que eu conheço. Para otimizar ainda mais, você poderia usar Object.GetHashCode () para obter um hash para o objeto, e usar isso como a chave do dicionário. Deve ser rápido, a menos que você está falando sobre árvores enormes de objetos (10s a 100s de milhares de objetos).
Não que eu estou familiarizado com C #, mas normalmente qualquer tipo de rastreamento de um gráfico para algum tipo de processamento exigirá uma tabela de referência para parar o processamento de um objeto devido a referências cíclicas. Então eu acho que você vai precisar fazer o mesmo aqui.
talvez criar uma bandeira bit para indicar se este objeto foi clonado antes.
Outra solução possível você poderia investigar é a serialização de objetos em um fluxo, e depois reconstruí-los a partir desse mesmo fluxo em novos casos. Isso muitas vezes faz maravilhas quando tudo parece muito complicado e confuso.
Marc
Uma das maneiras práticas para fazer clonagem profunda é serialização e, em seguida, desserializar um gráfico fonte. Alguns serializers em .NET como DataContractSerializer
são ainda capaz de processar ciclos dentro gráficos . Você pode escolher quais serializer é a melhor escolha para o seu cenário, olhando para a comparação de recursos traçar .