Introduction:
In C #, System. Object is the base class of all class types, structure types, enumeration types, and delegate types. It can be said that it is the basis of type inheritance. System. Object includes a member method used to create a copy of the current Object instance for MemberwiseClone.
Problem description:
The MemberwiseClone method of System. Object creates a shortest copy of a new Object, and copies the non-static fields of the current Object instance to the new Object instance. Through the attribute, the object copy can be correctly executed: If the attribute is a value type, the data is copied by bit. If the attribute is a reference type, the reference of the original object is copied, that is, the cloned object points to the same object instance. This means that the MemberwiseClone method does not create a deep copy of an object.
Solution:
There are many methods to implement deep copy of class objects. Below I will introduce two of them through examples:
1. Deep copy through serialization and deserialization
2. Deep copy through reflection
1. Deep object copying through serialization and deserialization
The ICloneable interface allows developers to customize the Clone method to create a deep copy of an existing object. Generally, the Object. MemberwiseClone method helps developers create a copy of an existing Object, but creates a shortest copy of the Object. Serialization refers to the process of storing the object state as a binary stream, while deserialization refers to the process of converting binary stream into the original object. There are many methods in. Net to achieve serialization and deserialization, such as binary serialization, XML serialization, and data Convention serialization. Binary serialization is faster than XML serialization, and binary serialization uses private and public fields. Therefore, binary serialization is a good choice for serialization and deserialization.
Through serialization and deserialization, you can create deep copies of objects. Note that all types can be serialized and deserialized only when marked as [serializable.
Example program:
First, create the Employee class, which contains the Department type attributes. The Employee class inherits the ICloneable interface and implements the Clone method. The binary formater is used to serialize and deserialize objects into a new object.
{_ Inclumentid = {_ DepartmentName = {_ EmployeeID = {_ EmployeeName = {_ Dempartment = (MemoryStream stream = (BinaryFormatter formatter = formatter. serialize (stream, stream. position =}View Code
You can also use the extension method:
T CopyObject<T>( (MemoryStream stream = BinaryFormatter formatter = stream.Position = }
2. Deep copy through reflection
Reflection is used to obtain the original information of the runtime object. You can use the System. Reflection namespace class to obtain information about the running history object, create a type instance from the existing object, and access its attributes and call methods. Considering the code, I created a static method that accepts Object parameters and returned a new instance of the same type.
CloneObject (Type typeSource = objTarget = PropertyInfo [] propertyInfo = typeSource. getProperties (BindingFlags. public | BindingFlags. nonPublic | (PropertyInfo property (property. propertyType. isValueType | property. propertyType. isEnum | property. propertyType. equals (property. setValue (objTarget, property. getValue (objSource,), objPropertyValue = property. getValue (objSource, (objPropertyValue = property. setValue (objTarget, property. setValue (objTarget, CloneObject (objPropertyValue ),}View Code
This can also be achieved through the following extension methods.
CloneObject (Type typeSource = objTarget = PropertyInfo [] propertyInfo = typeSource. getProperties (BindingFlags. public | BindingFlags. nonPublic | (PropertyInfo property (property. propertyType. isValueType | property. propertyType. isEnum | property. propertyType. equals (property. setValue (objTarget, property. getValue (objSource,), objPropertyValue = property. getValue (objSource, (objPropertyValue = property. setValue (objTarget, property. setValue (objTarget, objPropertyValue. cloneObject (),}View Code
The following is the sample code and output:
Main (Employee emp = emp. employeeID = emp. employeeName = emp. department = Department {partition mentid =, DepartmentName = Employee empClone = emp. clone () Employee empClone1 = Utility. cloneObject (emp) Employee empClone2 = emp. cloneObject () Employee empClone3 = emp. copyObject <Employee> emp. employeeName = emp. department. departmentName = Console. writeLine (+ Console. writeLine (+ Console. writeLine (Console. writeLine (+ Console. writeLine (+ Console. writeLine (Console. writeLine (+ Console. writeLine (+ Console. writeLine (Console. writeLine (+ Console. writeLine (+ Console. writeLine (}View Code
Conclusion:
Through serialization and reflection, we can achieve deep object copying. The only drawback of deep Copy Using serialization is that the object must be marked as Serializable.