Copiar un List en otro (Por valor no por referencia)

Iniciado por BlaineMonkey, 16 Febrero 2010, 12:46 PM

0 Miembros y 1 Visitante están viendo este tema.

BlaineMonkey

¿Hay algún método que copie de un List a otro sin que sea por referencia? Es decir que pueda modificar cualquiera de los dos y los cambios no se afecten en ambos List.

He probado a pasarle la lista en el constructor, pero esto lo hace por referencia.

¿La única manera es recorrer la lista original e ir creando los nuevos objetos con los mismos valores que la original?

raul338

Exacto....sino serializas la lista en memoria y despues lo vuelcas a la nueva lista. Obtienes una nueva lista literalmente igual a la primera, pero no son las mismas (con que cambies una, no cambia la otra)

http://msdn.microsoft.com/es-es/library/bb972188.aspx

es un ejemplo un poco largo, se puede "achicar", aunque no encuentro el articulo originial de donde lo aprendi :-\

BlaineMonkey


raul338

#3
Encontre mi proyecto de ejemplo :P
Si tienes esta clase (no importa que tenga propiedades, eventos, etc, se copia igual ;-)
Código (vbnet) [Seleccionar]

Class Persona
  Public Nombre as String
  Public Apellido as String
End Class


Lo que haces es agregarle el atributo Serializable, y si quieres la interfaz IClonable que te agrega el metodo Clone (aunque no recuerdo porque no me funciono a mi, asi que implemente el metodo Clonar solo :P
No olvides de importar los espacios de nombres, son vitales para que funcione el codigo

Te quedaria asi

Código (vbnet) [Seleccionar]

Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

<Serializable()> _
Class Persona
  Public Nombre as String
  Public Apellido as String

  Public Function Clonar() As Persona
  End Function
End Class


y en la funcion Clonar pones esto:

Código (vbnet) [Seleccionar]

       Dim clon As Persona  ' Objeto donde se va a copiar por valor

       ' Serializadores, objeto en memoria
       Dim formatter As IFormatter = New BinaryFormatter()
       Dim str As Stream = New MemoryStream()

       formatter.Serialize(str, Me)  ' Copiamos a un stream en la memoria
       str.Seek(0, SeekOrigin.Begin) ' Vamos al principio para volver a "leer"
       clon = CType(formatter.Deserialize(str), Persona) ' Lo leemos y lo guardamos en el objeto "clonado"

       Return clon


Por lo cual todo junto te quedaria asi:

Código (vbnet) [Seleccionar]

Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

<Serializable()> _
Class Persona
  Public Nombre as String
  Public Apellido as String

  Public Function Clonar() As Persona
       Dim clon As Persona

       Dim formatter As IFormatter = New BinaryFormatter()
       Dim str As Stream = New MemoryStream()

       formatter.Serialize(str, Me)
       str.Seek(0, SeekOrigin.Begin)
       clon = CType(formatter.Deserialize(str), Persona)

       Return clon
  End Function
End Class


Tal vez alguno diga que tenga un par de bugs o algo asi. Nose, a mi me funciono  ;-) jeje

Espero que te sirva!

Nota: La funcion Clonar esa sirve literalmente para cualquier cosa, se puede adaptar para clonar cualquier clase del net framework (el unico requisito es que sea serializable ovbio no? :P)

Skeletron

Tio.. creo que existe el metodo CLONE o COPY en los arrays... ese metodo hace la COPIA.. sin referencia...
Si mal no recuerdo

raul338

Solo en los arrays. El metodo que di funciona (sean arrays o no) para clases personalizadas uqe por defecto se copian por referencia