Reflection-Based Cloning Implementation
This approach uses reflection to create deep clones of objects:
public abstract class CloneableBase : ICloneable
{
public object Clone()
{
object cloneInstance = Activator.CreateInstance(GetType());
FieldInfo[] cloneFields = cloneInstance.GetType().GetFields();
int index = 0;
foreach (FieldInfo field in GetType().GetFields())
{
if (field.FieldType.GetInterface("ICloneable") != null)
{
ICloneable original = (ICloneable)field.GetValue(this);
cloneFields[index].SetValue(cloneInstance, original.Clone());
}
else
{
cloneFields[index].SetValue(cloneInstance, field.GetValue(this));
}
if (field.FieldType.GetInterface("IEnumerable") != null)
{
IEnumerable collection = (IEnumerable)field.GetValue(this);
IList list = cloneFields[index].GetValue(cloneInstance) as IList;
IDictionary dictionary = cloneFields[index].GetValue(cloneInstance) as IDictionary;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i] is ICloneable cloneableItem)
{
list[i] = cloneableItem.Clone();
}
}
}
else if (dictionary != null)
{
foreach (DictionaryEntry entry in dictionary)
{
if (entry.Value is ICloneable cloneableValue)
{
dictionary[entry.Key] = cloneableValue.Clone();
}
}
}
}
index++;
}
return cloneInstance;
}
}
Serialization-Based Cloning
Binary seiralization provides a simple deep cloning mechanism:
public static class ObjectCloner
{
public static T CreateDeepCopy<t>(T original)
{
using (MemoryStream buffer = new MemoryStream())
{
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(buffer, original);
buffer.Position = 0;
return (T)serializer.Deserialize(buffer);
}
}
}</t>
XML Serialization Approach
public interface IDeepCloner<t> where T : class
{
T CreateClone(T source);
}
public class XmlCloner<t> : IDeepCloner<t> where T : class
{
public T CreateClone(T source)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, source);
stream.Position = 0;
return (T)serializer.Deserialize(stream);
}
}
}</t></t></t>
Recursive Field Cloning Technique
public class ObjectCopier
{
public T CopyObject<t>(T source) where T : class
{
if (source == null || source is string) return source;
T clone = CreateInstance(source.GetType());
CopyFields(source, clone);
ProcessBaseFields(source, clone);
return clone;
}
private T CreateInstance<t>(Type objectType)
{
try
{
return (T)Activator.CreateInstance(objectType);
}
catch
{
foreach (ConstructorInfo ctor in objectType.GetConstructors(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
ParameterInfo[] parameters = ctor.GetParameters();
object[] args = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i].ParameterType.IsValueType)
{
args[i] = Activator.CreateInstance(parameters[i].ParameterType);
}
}
return (T)ctor.Invoke(args);
}
}
return default(T);
}
private void CopyFields<t>(T source, T target)
{
foreach (FieldInfo field in source.GetType().GetFields(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
if (field.FieldType.IsValueType || field.FieldType == typeof(string))
{
field.SetValue(target, field.GetValue(source));
}
else
{
field.SetValue(target, CopyObject(field.GetValue(source)));
}
}
}
private void ProcessBaseFields<t>(T source, T target)
{
Type baseType = source.GetType().BaseType;
while (baseType != typeof(object))
{
foreach (FieldInfo field in baseType.GetFields(
BindingFlags.NonPublic | BindingFlags.Instance))
{
if (field.IsPrivate)
{
if (field.FieldType.IsValueType || field.FieldType == typeof(string))
{
field.SetValue(target, field.GetValue(source));
}
else
{
field.SetValue(target, CopyObject(field.GetValue(source)));
}
}
}
baseType = baseType.BaseType;
}
}
}</t></t></t></t>