I\'ve found numerous solutions here at SO and elsewere that deal with deep clone of object via serialization/deserialization (into memory and back).
It requires that
Json serialization and deserialization should work, it doesn't require the classes to have serialize annotation.
public static T DeepCopy<T>(this T source)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(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;
}
This 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);
}
}