2009-03-25 29 views
5

¿Cuál es la mejor forma de deep clonar un conjunto de objetos interconectados? Ejemplo:¿Cómo clonar profundamente los objetos interconectados en C#?

class A { 
    B theB; // optional 
    // ... 
} 

class B { 
    A theA; // optional 
    // ... 
} 

class Container { 
    A[] a; 
    B[] b; 
} 

Lo obvio que hacer es caminar los objetos y clon todo lo profundo que llegue a él. Sin embargo, esto crea un problema: si clono un A que contiene un B, y ese B también está en el Container, ese B se clonará dos veces después de clonar el Container.

El siguiente paso lógico es crear un Dictionary y buscar cada objeto antes de clonarlo. Sin embargo, parece que podría ser una solución lenta y desvergonzada.

¿Alguna idea?

+0

he aquí cómo lo hago: http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

Respuesta

2

No es una solución elegante, pero no es raro usar un diccionario (o hashmap). Una de las ventajas es que un hashmap tiene un tiempo de búsqueda constante, por lo que la velocidad realmente no sufre aquí.

2

La solución de diccionario que sugirió es la mejor que conozco. Para optimizar aún más, puede usar object.GetHashCode() para obtener un hash para el objeto y usarlo como la clave del diccionario. Debería ser rápido a menos que esté hablando de enormes árboles de objetos (10 a 100 de miles de objetos).

2

No estoy familiarizado con C#, pero generalmente cualquier tipo de rastreo de un gráfico para algún tipo de procesamiento requerirá una tabla de búsqueda para detener el procesamiento de un objeto debido a las referencias cíclicas. Entonces, creo que tendrías que hacer lo mismo aquí.

0

puede crear una bandera de bit para indicar si este objeto se ha clonado antes.

0

Otra posible solución que podría investigar es serializar los objetos en una secuencia, y luego reconstruirlos a partir de la misma secuencia en nuevas instancias. Esto a menudo funciona de maravilla cuando todo lo demás parece terriblemente complicado y desordenado.

Marc

+0

¿Puede dar más detalles? ¿Cómo podría evitar serializar el mismo objeto dos veces? O si solo serializo "Contenedor", ¿cómo podría almacenar * referencias * a A y B en lugar de a todo el objeto, para evitar la duplicación? No puedo usar un índice simple como lo creería del simple ejemplo. – zildjohn01

+0

WCF lo admite con algunos ajustes (http://blogs.msdn.com/sowmy/archive/2006/03/26/561188.aspx). Pero la serialización, aunque es rápida de codificar, va a funcionar mucho peor que una copia profunda explícita. –

+0

Verdadero: serializar y deserializar de nuevo podría no ser el mejor en términos de rendimiento. Esto se reduce al eterno escenario de "depende" :-) ¿Necesita un rendimiento superior y lo hace cientos de miles de veces en un bucle?> Entonces la serialización podría no ser la mejor ruta para tomar. –

Cuestiones relacionadas