Implementing Deep and Shallow Cloning in C#

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>

Tags: C# Object Cloning deep copy reflection serialization

Posted on Sat, 29 Aug 2026 16:32:34 +0000 by davidska