[c#] How to Clone Objects

When I do the following.. anything done to Person b modifies Person a (I thought doing this would clone Person b from Person a). I also have NO idea if changing Person a will change Person b after the linking. Due to my code right now, I can only see this in 1 direction.

Person a = new Person() { head = "big", feet = "small" };
Person b = a; 

b.head = "small"; //now a.head = "small" too   

Now if I do this instead.. Person a becomes completely separate.

Person b = new Person() { head = a.head, feet = a.feet };

Now this fine and kinda makes sense when comparing this behaviour to other things in C#. BUT, this could get very annoying with large objects.

Is there a way to shortcut this at all?

Such as:

Person b = a.Values;

This question is related to c# object

The answer is


It couldn't be simpler than this:

    public SomeClass Clone () {

        var clonedJson = JsonConvert.SerializeObject (this);

        return JsonConvert.DeserializeObject<SomeClass> (clonedJson);
    }

Just serialize any object to a JSON string and then deserialize it. This will do a deep copy...


Painlessly: Using NClone library

Person a = new Person() { head = "big", feet = "small" };
Person b = Clone.ObjectGraph(a); 

What you are looking is for a Cloning. You will need to Implement IClonable and then do the Cloning.

Example:

class Person() : ICloneable
{
    public string head;
    public string feet; 

    #region ICloneable Members

    public object Clone()
    {
        return this.MemberwiseClone();
    }

    #endregion
}

Then You can simply call the Clone method to do a ShallowCopy (In this particular Case also a DeepCopy)

Person a = new Person() { head = "big", feet = "small" };
Person b = (Person) a.Clone();  

You can use the MemberwiseClone method of the Object class to do the cloning.


This happens because "Person" is a class, so it is passed by reference. In the statement "b = a" you are just copying a reference to the one and only "Person" instance that you created with the keyword new.

The easiest way to have the behavior that you are looking for is to use a "value type".

Just change the Person declaration from

class Person

to

struct Person

Since the MemberwiseClone() method is not public, I created this simple extension method in order to make it easier to clone objects:

public static T Clone<T>(this T obj)
{
    var inst = obj.GetType().GetMethod("MemberwiseClone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

    return (T)inst?.Invoke(obj, null);
}

Usage:

var clone = myObject.Clone();

This code worked for me. It also takes a very small amount of time to execute.

    public static void CopyTo(this object Source, object Destination)
    {
        foreach (var pS in Source.GetType().GetProperties())
        {
            foreach (var pT in Destination.GetType().GetProperties())
            {
                if (pT.Name != pS.Name) continue;
                (pT.GetSetMethod()).Invoke(Destination, new object[]
                { pS.GetGetMethod().Invoke( Source, null ) });
                break;
            }
        };
    }

MemberwiseClone is a good way to do a shallow copy as others have suggested. It is protected however, so if you want to use it without changing the class, you have to access it via reflection. Reflection however is slow. So if you are planning to clone a lot of objects it might be worthwhile to cache the result:

public static class CloneUtil<T>
{
    private static readonly Func<T, object> clone;

    static CloneUtil()
    {
        var cloneMethod = typeof(T).GetMethod("MemberwiseClone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        clone = (Func<T, object>)cloneMethod.CreateDelegate(typeof(Func<T, object>));
    }

    public static T ShallowClone(T obj) => (T)clone(obj);
}

public static class CloneUtil
{
    public static T ShallowClone<T>(this T obj) => CloneUtil<T>.ShallowClone(obj);
}

You can call it like this:

Person b = a.ShallowClone();

In my opinion, the best way to do this is by implementing your own Clone() method as shown below.

class Person
{
    public string head;
    public string feet;

    // Downside: It has to be manually implemented for every class
    public Person Clone()
    {
        return new Person() { head = this.head, feet = this.feet };
    }
}

class Program
{
    public static void Main(string[] args)
    {
        Person a = new Person() { head = "bigAF", feet = "smol" };
        Person b = a.Clone();

        b.head = "notEvenThatBigTBH";

        Console.WriteLine($"{a.head}, {a.feet}");
        Console.WriteLine($"{b.head}, {b.feet}");
    }
}

Output:

bigAf, smol

notEvenThatBigTBH, smol

b is totally independent to a, due to it not being a reference, but a clone.

Hope I could help!


You could do it like this:

var jss = new JavaScriptSerializer();
var b = jss.Deserialize<Person>(jss.Serialize(a));

For deep cloning you may want to take a look at this answer: https://stackoverflow.com/a/78612/550975


  public static T Clone<T>(T obj)
  {
      DataContractSerializer dcSer = new  DataContractSerializer(obj.GetType());
      MemoryStream memoryStream = new MemoryStream();

      dcSer.WriteObject(memoryStream, obj);
      memoryStream.Position = 0;

      T newObject = (T)dcSer.ReadObject(memoryStream);
      return newObject;
  }

a and b are just two references to the same Person object. They both essentially hold the address of the Person.

There is a ICloneable interface, though relatively few classes support it. With this, you would write:

Person b = a.Clone();

Then, b would be an entirely separate Person.

You could also implement a copy constructor:

public Person(Person src)
{
  // ... 
}

There is no built-in way to copy all the fields. You can do it through reflection, but there would be a performance penalty.


To clone your class object you can use the Object.MemberwiseClone method,

just add this function to your class :

public class yourClass
{
    // ...
    // ...

    public yourClass DeepCopy()
    {
        yourClass othercopy = (yourClass)this.MemberwiseClone();
        return othercopy;
    }
}

then to perform a deep independant copy, just call the DeepCopy method :

yourClass newLine = oldLine.DeepCopy();

I use AutoMapper for this. It works like this:

Mapper.CreateMap(typeof(Person), typeof(Person));
Mapper.Map(a, b);

Now person a has all the properties of person b.

As an aside, AutoMapper works for differing objects as well. For more information, check it out at http://automapper.org

Update: I use this syntax now (simplistically - really the CreateMaps are in AutoMapper profiles):

Mapper.CreateMap<Person, Person>;
Mapper.Map(a, b);

Note that you don't have to do a CreateMap to map one object of the same type to another, but if you don't, AutoMapper will create a shallow copy, meaning to the lay man that if you change one object, the other changes also.