So I\'m trying to find a generic extension method that creates a deep copy of an object using reflection, that would work in Silverlight. Deep copy using serialization is no
Required Namespaces:
using System.Reflection;
using System.Collections.Generic;
Method:
private readonly static object _lock = new object();
public static T cloneObject<T>(T original, List<string> propertyExcludeList)
{
try
{
Monitor.Enter(_lock);
T copy = Activator.CreateInstance<T>();
PropertyInfo[] piList = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (PropertyInfo pi in piList)
{
if (!propertyExcludeList.Contains(pi.Name))
{
if (pi.GetValue(copy, null) != pi.GetValue(original, null))
{
pi.SetValue(copy, pi.GetValue(original, null), null);
}
}
}
return copy;
}
finally
{
Monitor.Exit(_lock);
}
}
This is not specific to Silverlight in any way - it is just plain Reflection.
As written it will only work with objects that have a parameterless constructor. To use objects that require constructor parameters, you will need to pass in an object[] with the parameters, and use a different overload of the Activator.CreateInstance method e.g.
T copy = (T)Activator.CreateInstance(typeof(T), initializationParameters);
The propertyExcludeList parameter is a list of property names that you wish to exclude from the copy, if you want to copy all properties just pass an empty list e.g.
new List<string>()
Can't you just use regular .NET reflection? Serialize your object to a MemoryStream
and then deserialize it back. This will create a deep copy (ultimately using reflection) and will require hardly any code on your part:
T DeepCopy<T>(T instance)
{
BinaryFormatter formatter=new BinaryFormatter();
using(var stream=new MemoryStream())
{
formatter.Serialize(stream, instance);
stream.Position=0;
return (T)formatter.Deserialize(stream);
}
}
For data contract objects we have used the following helper method for deep cloning within Silverlight:
public static T Clone<T>(T source)
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, source);
ms.Seek(0, SeekOrigin.Begin);
return (T)serializer.ReadObject(ms);
}
}
Used like this:
var clone = CloneHelper.Clone<MyDTOType>(dtoVar);