En Visual Basic, a menudo es necesario crear una copia de un objeto para modificar los datos de una nueva manera, sin afectar la estructura original. Surge la tarea de distinguir entre la copia superficial (shallow) y la copia profunda (deep), especialmente si los objetos contienen tipos de referencia anidados.
Historia de la cuestión:
La copia superficial copia solo los valores de las propiedades primitivas y las referencias a los objetos anidados, mientras que la copia profunda crea nuevas instancias de todos los objetos anidados. La diferencia es fundamental al trabajar con datos complejos, por ejemplo, si un objeto contiene colecciones u otros objetos.
Problema:
Si se copia un objeto por referencia o se utiliza el método estándar MemberwiseClone, al modificar los objetos anidados, la estructura original se modificará junto con la copia; esto es peligroso para la lógica del negocio y puede llevar a errores difíciles de detectar.
Solución:
En VB.NET no hay una implementación directa para una copia profunda, por lo tanto, debe ser implementada manualmente o mediante serialización. Normalmente se implementa un método personalizado DeepCopy, creando nuevas instancias de todos los objetos anidados.
Ejemplo de código de copia superficial y profunda:
Class Person Public Name As String Public Address As Address ' Copia superficial Public Function ShallowCopy() As Person Return CType(Me.MemberwiseClone(), Person) End Function ' Copia profunda Public Function DeepCopy() As Person Dim copy As Person = CType(Me.MemberwiseClone(), Person) copy.Address = New Address() With {.City = Me.Address.City} Return copy End Function End Class Class Address Public City As String End Class
Características clave:
¿Qué devolverá el operador = al copiar un objeto de clase en Visual Basic?
Respuesta: El operador = para tipos de referencia asigna una referencia, no copia valores. Por lo tanto, ambas variables apuntarán al mismo objeto.
Dim a As New Person() Dim b As Person = a ' Ahora a y b son referencias al mismo objeto
¿Se puede usar MemberwiseClone para una copia profunda?
Respuesta: No. El método MemberwiseClone solo implementa la copia superficial; todos los tipos de referencia anidados se copian por referencia.
¿Por qué la serialización no siempre es un método universal para la copia profunda?
Respuesta: La serialización solo funciona con objetos serializables y puede no soportar propiedades con tipo Object o no marcadas como Serializable. Además, la serialización es más lenta que la copia estándar.
Un cliente copia un objeto de pedido usando el operador = para realizar un nuevo pedido, sin saber que la lista anidada de elementos queda compartida entre los dos objetos.
Ventajas: Rápido, simple
Desventajas: Cambios en un pedido afectan el otro — errores críticos en la contabilización de mercancías.
Se ha implementado el método DeepCopy para copiar un pedido junto con todos los productos anidados y la dirección de envío.
Ventajas: Separación confiable de datos, lógica de negocio correcta
Desventajas: Se necesita prestar atención a la estructura del objeto, más código para mantener