Quiero hacer una copia profunda de un objeto para poder cambiar la nueva copia y aún tener la opción de cancelar mis cambios y recuperar el objeto original.Crear una copia profunda en C#
Mi problema aquí es que el objeto puede ser de cualquier tipo, incluso de un ensamblaje desconocido. No puedo usar BinaryFormatter
o XmlSerializer
, porque el objeto innecesariamente tiene el atributo [Serializable].
he tratado de hacer esto utilizando el método Object.MemberwiseClone()
:
public object DeepCopy(object obj)
{
var memberwiseClone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
var newCopy = memberwiseClone.Invoke(obj, new object[0]);
foreach (var field in newCopy.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
if (!field.FieldType.IsPrimitive && field.FieldType != typeof(string))
{
var fieldCopy = DeepCopy(field.GetValue(newCopy));
field.SetValue(newCopy, fieldCopy);
}
}
return newCopy;
}
El problema de esto es que no está trabajando en un enumerable (matriz, lista, etc), no en un diccionario.
Entonces, ¿cómo puedo hacer una copia profunda de un objeto desconocido en C#?
TNX mucho!
La invocación de 'MemberwiseClone' en un objeto arbitrario es _evil_. – SLaks
He probado esto en matrices y diccionarios, y ambos parecen funcionar.Agregué un cheque al principio para null. Esto parece una solución de propósito general para objetos básicos. Como Slaks mencionó, no es una buena idea para filestreams y, por ejemplo, copiará el mismo identificador para la secuencia de archivos. Ambos dependerán de la secuencia de cierre o búsqueda. Si eres consciente de que no siempre es un clon profundo, es una solución interesante. –
También he leído una solución en la que puede verificar la interfaz ICloneable. Si se implementa ICloneable, invoca de lo contrario solo crea una instancia vacía. –