Cloning objects without serialization

I found many solutions here in SO and others that relate to deep cloning of an object through serialization / deserialization (in memory and vice versa).

This requires that the classes to be cloned are marked [Serializable] . I have my classes (well, most of them) marked with [DataContract] because I use the DataContractSerializer for serialization in XML.

I only introduced the [Serializable] attribute due to the need for deep cloning of some of these class instances. However, now something has happened with serialization / deserialization through DCS, because it no longer works - errors waiting to use another XML element for deserialization. If I remove [Serializable] , the errors go away.

What are my options? I just want to deeply clone my objects as simple as possible.

+6
source share
3 answers

It works

  public static T DeepClone<T>(this T a) { using (MemoryStream stream = new MemoryStream()) { DataContractSerializer dcs = new DataContractSerializer(typeof(T)); dcs.WriteObject(stream, a); stream.Position = 0; return (T)dcs.ReadObject(stream); } } 
+10
source

Json serialization and deserialization should work, but do not require classes to have annotation serialization.

 public static T DeepCopy<T>(this T source) { return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source)); } 
+1
source

Here's how to use it:

 var oldList = new List<int>(); var newList = oldList.Clone(); 

using these methods:

 public static T Clone<T>(this T o) where T : new() { return (T)CloneObject(o); } static object CloneObject(object obj) { if (ReferenceEquals(obj, null)) return null; var type = obj.GetType(); if (type.IsValueType || type == typeof(string)) return obj; else if (type.IsArray) { var array = obj as Array; var arrayType = Type.GetType(type.FullName.Replace("[]", string.Empty)); var arrayInstance = Array.CreateInstance(arrayType, array.Length); for (int i = 0; i < array.Length; i++) arrayInstance.SetValue(CloneObject(array.GetValue(i)), i); return Convert.ChangeType(arrayInstance, type); } else if (type.IsClass) { var instance = Activator.CreateInstance(type); var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (var field in fields) { var fieldValue = field.GetValue(obj); if (ReferenceEquals(fieldValue, null)) continue; field.SetValue(instance, CloneObject(fieldValue)); } return instance; } else return null; } 
0
source

Source: https://habr.com/ru/post/906441/


All Articles