Click here to Skip to main content
15,116,253 members
Articles / Web Development / ASP.NET / ASP.NET4.0
Posted 20 Sep 2016


12 bookmarked

Implementing Deep Cloning using Reflection

Rate me:
Please Sign up or sign in to vote.
4.20/5 (6 votes)
20 Sep 2016CPOL
How to implement deep cloning using Reflection


In my line of work, I have many big objects that need to be able to handle advanced calculations and validation. I needed to be able to make changes to objects' properties and then revoke the changes if needed.

The easiest way was to DeepClone the object. The problem was that there are too many libraries out there that were too hard to customize to my requirements and were too slow, so I decided to make my own.


Using the Code

This is the class that will perform the DeepClone, and also the object does not need to be [Serializable].

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;

namespace FastDeepCloner
        #region Privat Properties
        private const BindingFlags Binding = BindingFlags.Instance | 
        BindingFlags.NonPublic |  BindingFlags.Public | BindingFlags.FlattenHierarchy;
        private readonly Type _primaryType;
        private readonly object _desireObjectToBeCloned;

        #region Contructure
        public FastDeepCloner(object desireObjectToBeCloned)
            if (desireObjectToBeCloned == null)
                throw new Exception("The desire object to be cloned cant be NULL");
            _primaryType = desireObjectToBeCloned.GetType();
            _desireObjectToBeCloned = desireObjectToBeCloned;

        #region Privat Method Deep Clone
       // Clone the object Properties and its children recursively
        private object DeepClone()
            if (_desireObjectToBeCloned == null)
                return null;
            if (_primaryType.IsArray)
                return ((Array)_desireObjectToBeCloned).Clone();
            object tObject = _desireObjectToBeCloned as IList;
            if (tObject != null)
                var properties = _primaryType.GetProperties();
                // Get the IList Type of the object
                var customList = typeof(List<>).MakeGenericType
                                 ((properties[properties.Length - 1]).PropertyType);
                tObject = (IList)Activator.CreateInstance(customList);
                var list = (IList)tObject;
                // loop throw each object in the list and clone it
                foreach (var item in ((IList)_desireObjectToBeCloned))
                    if (item == null)
                    var value = new FastDeepCloner(item).DeepClone();
                // if the item is a string then Clone it and return it directly.
                if (_primaryType == typeof(string))  
                    return (_desireObjectToBeCloned as string)?.Clone();

                // Create an empty object and ignore its construtore.
                tObject = FormatterServices.GetUninitializedObject(_primaryType);
                var fields = _desireObjectToBeCloned.GetType().GetFields(Binding);
                foreach (var property in fields)
                    if (property.IsInitOnly) // Validate if the property is a writable one.
                    var value = property.GetValue(_desireObjectToBeCloned);
                    if (property.FieldType.IsClass && property.FieldType != typeof(string))
                        tObject.GetType().GetField(property.Name, Binding)?.SetValue
                        (tObject, new FastDeepCloner(value).DeepClone());
                        tObject.GetType().GetField(property.Name, Binding)?.SetValue(tObject, value);

            return tObject;

        #region public Method Clone
        public object Clone()
            return DeepClone();
        public T Clone<T>()
            return (T)DeepClone();

Ways to use this class are listed below:

  1. Employee employee = new FastDeepCloner.FastDeepCloner(original).Clone<Employee>();
  2. List<Employee> employee = new FastDeepCloner.FastDeepCloner(original).Clone<List<Employee>>();
  3. object employee = new FastDeepCloner.FastDeepCloner(original).Clone(); // for System.Object

Points of Interest

I am waiting for your thoughts about this. I may make it more advanced by making it ignore properties and also by making it faster.


  • 2016-09-20: Version 1.0.1: released on NuGet


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Alen Toma
Software Developer (Senior)
Sweden Sweden
No Biography provided

Comments and Discussions

QuestionUsing Statics Pin
Nash Michael22-Sep-16 9:53
professionalNash Michael22-Sep-16 9:53 
AnswerRe: Using Statics Pin
Alen Toma22-Sep-16 10:25
MemberAlen Toma22-Sep-16 10:25 
QuestionArray cloning Pin
Philippe Mori21-Sep-16 7:16
MemberPhilippe Mori21-Sep-16 7:16 
It look like if the object is an array, you do a shallow copy by calling Array.Clone. I was think that the purpose of the class was to do a deep cloning so I don't understand.
Philippe Mori

AnswerRe: Array cloning Pin
Alen Toma21-Sep-16 7:28
MemberAlen Toma21-Sep-16 7:28 
GeneralRe: Array cloning Pin
Philippe Mori21-Sep-16 9:54
MemberPhilippe Mori21-Sep-16 9:54 
GeneralRe: Array cloning Pin
Alen Toma21-Sep-16 9:55
MemberAlen Toma21-Sep-16 9:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.