This explanation is not valid for immutable classes (strings, delegates, structures, etc), because these classes have other behaviors, and do not feature in this article.
For this, we will use two implementation techniques - ICloneable Interface and Extension Methods, depending on the type of cloning.
Class example
This is the class we will use for the examples.
- public class Customer: ICloneable {
- public int ID { get;
- set; }
- public string Name { get;
- set; }
- public decimal Sales { get;
- set; }
- public DateTime EntryDate { get;
- set; }
- public Address Adress { get;
- set; }
- public Collection < string > Mails { get;
- set; }
- protected string Data1 { get;
- set; }
- private string Data2 { get;
- set; }
- public Customer() {
- Data1 = "data1";
- Data2 = "Data2";
- }
- public virtual object Clone() {}
- }
- Customer customer1 = new Customer { ID = 1, Name = "Test", City = "City", Sales = 1000m };
- Customer customer2 = customer1;

Customer1 and Customer2 are linked and any modification in an object will be reflected in the other object. To Clone is necessary for un-linking the object and its virtual copy; and they are independent objects.

ICloneable
- public interface ICloneable
- {
- object Clone();
- }
- Customer customer2 = (Customer)customer1.Clone();
- public static class MyExtensions {
- public static T CloneObject < T > (this object source) {
- T result = Activator.CreateInstance < T > ();
- //// **** made things
- return result;
- }
- }
- Customer Customer2 = customer1.CloneObject();
- public class Customer: ICloneable {
- // Properties ...
- public virtual object Clone() {
- return this.CloneObject();
- }
- }
Object.MemberWiseClone
- Structs Copies bit by bit the value of the property.
- Class Copies the reference of property, consequently, they are the same object.
The case class is a problem because both objects are the same. This is a lack of method.
The use of MemberWiseClone is usually done at the same as ICloneable Interface because the MemberWiseClone is a protected method and is mandatory to call internally.
MemberWiseClone example
- public class Customer: ICloneable {
- public int ID {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public decimal Sales {
- get;
- set;
- }
- public DateTime EntryDate {
- get;
- set;
- }
- public Address Adress {
- get;
- set;
- }
- public Collection < string > Mails {
- get;
- set;
- }
- protected string Data1 {
- get;
- set;
- }
- private string Data2 {
- get;
- set;
- }
- public Customer() {
- Data1 = "data1";
- Data2 = "Data2";
- }
- public virtual object Clone() {
- return this.MemberwiseClone();
- }
- }
- Easy for developers.
- Very little code to write.
- Easy to understand.
- It copies any fields/properties type (simple and complex).
- It doesn’t need to mark the class with any special attribute.
Cons
- It can be called inside the class only because it is a protected method.
- It must be implemented in all classes to clone.
- The reference properties of an object to clone can't be copied, they are linked.
- The clone method returns an object, consequently, we will have to do casting each time we use it.
If we try a completely in-depth copy, we have to do manual assignments of all references properties,
- public virtual object Clone()\
- {
- var result = this.MemberwiseClone();
- // Manual assignments
- result.Adress = new Address {
- City = this.Adress.City,
- Street = this.Adress.Street,
- ZipCode = this.Adress.ZipCode
- };
- result.Mails = new Collection < string > ();
- this.Mails.ToList().ForEach(a => result.Mails.Add(a));
- return result;
- }
- public static T CloneObjectSerializable < T > (this T obj) where T: class {
- MemoryStream ms = new MemoryStream();
- BinaryFormatter bf = new BinaryFormatter();
- bf.Serialize(ms, obj);
- ms.Position = 0;
- object result = bf.Deserialize(ms);
- ms.Close();
- return (T) result;
- }
- Customer customer2 = customer1.CloneObjectSerializable();

- [Serializable]
- public class Customer
- Easy for developer
- Easy to write in an Extension Method, therefore we implement once.
- It copies any fields/properties types (simple and complex)
- It implements a deep copy.
- It doesn’t necessarily call inside the class because it is an object extension method.
- Returns a Generic Type, therefore we don't have to apply boxing/unboxing.
Cons
- It needs to mark with a special attribute.
- For your implementation, it needs more code and logic.
This method can be used with ICloneable, which perfectly maintains all of its virtues.
- public virtual object Clone()
- {
- return this.CloneObjectSerializable();
- }

Andreas SeibelPosted Mar 10, 2021, 10:17 AM
You can also user Netwonsoft Json to Serialize / Desiarilize an Object: public static T Clone<T>(T source){ var serialized = JsonConvert.SerializeObject(source); return JsonConvert.DeserializeObject<T>(serialized); }
Anu VPosted Jan 18, 2017, 11:06 PM
Nice article thanks for sharing...
Juan Francisco Morales LariosPosted Dec 28, 2016, 4:53 AM
Thank you Fabio, There isn't perfect case, but MemberWiseClone + Manual reference types can be good solution, although somewhat more laborious.
Fabio Silva LimaPosted Dec 27, 2016, 8:10 PM
Very good Juan! Serialization is good but sometimes there are too manh errors
Juan Francisco Morales LariosPosted Dec 27, 2016, 11:20 AM
Nice, Thank you very much
Manas MohapatraPosted Dec 27, 2016, 8:00 AM
Nice explanation with pros and cons ..