Come profondo clone interconnessi oggetti in C #?
Domanda
Qual è il modo migliore per profonda clonare un insieme interconnesso di oggetti? Esempio:
class A {
B theB; // optional
// ...
}
class B {
A theA; // optional
// ...
}
class Container {
A[] a;
B[] b;
}
La cosa più ovvia da fare è camminare gli oggetti e profonda clone tutto come vengo ad esso. Questo crea un problema però -. Se mi clonare un A
che contiene un B
, e che B
è anche nel Container
, che B
verrà clonato due volte dopo che clonare il Container
Il prossimo passo logico è quello di creare un Dictionary
e cercare ogni oggetto prima di clonarlo. Questo sembra che potrebbe essere una soluzione lenta e sgraziata, tuttavia.
Qualche idea?
Soluzione
La sua non è una soluzione elegante di sicuro, ma non è raro usare un dizionario (o HashMap). Uno dei vantaggi è che un HashMap ha un tempo di ricerca costante, per cui la velocità in realtà non soffre qui.
Altri suggerimenti
La soluzione dizionario avete suggerito è il migliore che io conosca. Per ottimizzare ulteriormente, si potrebbe usare object.GetHashCode () per ottenere un hash per l'oggetto, e l'uso che come chiave del dizionario. Dovrebbe essere veloce a meno che non si sta parlando di alberi di oggetti enormi (10s a 100s di migliaia di oggetti).
Non è che mi è familiare con C #, ma in genere qualsiasi tipo di strisciare di un grafico per una sorta di trasformazione richiederà una tabella di ricerca per fermare l'elaborazione di un oggetto a causa di riferimenti ciclici. Così penserei è necessario fare lo stesso qui.
forse creare un flag di bit per indicare se questo oggetto è stato clonato prima.
Un'altra possibile soluzione si potrebbe indagare è la serializzazione degli oggetti in un flusso, e poi ricostruire da quella stessa corrente in nuove istanze. Questo funziona spesso si chiede quando tutto il resto sembra terribilmente contorta e disordinato.
Marc |
Uno dei modi pratici per fare profonda clonazione viene serializzazione e deserializzazione poi un grafico sorgente. Alcuni serializzatori in .NET come DataContractSerializer
sono anche grado di elaborare cicli nei grafici . È possibile scegliere quale serializzatore è la scelta migliore per lo scenario, cercando in il confronto delle funzionalità grafico .