How to clone with Silverlight without ICloneable?
Posted on: 2011-10-13
The .Net Framework allow to clone ICloneable interface. This interface has a single method that is Clone. This interface is not available in Silverlight. The reason is that Microsoft have found that since it does not provide specification between deep copy or shallow copy that it was useless to port this interface into the Silverlight SDK. In fact, this interface has been questionable since a long time ago.
An other way to clone is to serialize and deserialize your object. By using this mechanism all references are not there but the value are. The problem, is that Silverlight does not have the System.Runtime.Serialization has you may know in the .Net standard framework. You won't fine the the IFormatter interface neither the BinaryFormatter class.
So, how to clone an object in Silverlight?
Here is a cloning method that is an extension for every object. It uses reflection to do it's cloning. This is not a deep copy!
public static class CloningExtension {
public static T Clone<T>(this T source) {
T cloned = (T) Activator.CreateInstance(source.GetType());
foreach (PropertyInfo curPropInfo in source.GetType().GetProperties()) {
if (curPropInfo.GetGetMethod() != null && (curPropInfo.GetSetMethod() != null)) {
// Handle Non-indexer properties
if (curPropInfo.Name != "Item") {
// get property from source object
getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// set property on cloned
curPropInfo.GetSetMethod().Invoke(cloned, new object[] {getValue});
}
// handle indexer
else {
// get count for indexer
int numberofItemInColleciton =(int)curPropInfo.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(source, new object[] {});
// run on indexer
for (int i = 0; i < numberofItemInColleciton; i++) {
// get item through Indexer object
getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {i});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// add item to collection
curPropInfo.ReflectedType.GetMethod("Add").Invoke(cloned, new object[] {getValue});
}
}
}
}
return cloned;
}
}
If you want more information you can read this forum thread.