Problem origin:
Yesterday, I was asked by my colleagues about the difference between the shallow copy and the deep copy. To be honest, I remember reading the concepts and differences when I was at school.
However, at that time, there were several other students who could read and understand the books as much as possible.
Although Clone-related content is also useful after work, it is only an application, and the basic concepts are not carefully understood, these concepts were mixed in the subsequent copies of the schema inside the DataTable.
Once thought:
More than a year ago, I went to the interview and was asked by a person about the difference between the shallow copy and the deep copy. A: The shallow copy means that the copy architecture does not include the value, deep copy means that the values are also copied together.
When I answered the wrong answer, the other party did not correct it, but seemed quite satisfied with my answer.
Alas, the interview manager still asked me this question, and I thought it was the case till now.
Colleague's question:
My colleague said that in the example, I found that the value was copied, so I realized that I had a problem with my cognition. I retried Baidu.
The answer to the "7 + 8" disorder on the Internet gave me a vague and seemingly correct answer: do not copy objects of internal classes in a shortest copy.
The resulting confusion:
My colleagues' questions once led me to this confusing error abyss: The copy address of the reference type is the copy address of the shallow copy, and the value type is directly copied.
Finally, in order to solve the problem, let's use the example:
Class DemoClass: ICloneable
{
Public int intValue = 1;
Public string strValue = "1 ";
Public PersonEnum pEnum = PersonEnum. EnumA;
Public PersonStruct pStruct = new PersonStruct ();
Public Person pClass = new Person ("1"); public int [] pIntArray = new int [] {1 };
Public string [] pArray = new string [] {"1 "};
# Region ICloneable Member
Public DemoClass ()
{
PStruct. StructValue = 1;
}
Public object Clone ()
{
Return this. MemberwiseClone ();
}
# Endregion
}
Class Person
{
Public string Name;
Public Person (string name)
{
Name = name;
}
}
Public enum PersonEnum
{
EnumA = 1,
EnumB = 2
}
Public struct PersonStruct
{
Public int StructValue;
}
Note:
The example here is used:
Int
Stringint []
String []
Enum
Struct
Class
Then, instance A and instance B will be generated.
Then, change the value of B to see if the value of A is changed.
Next let's look at the main method.
Static void Main (string [] args)
{
Demo ();
}
Public static void Demo ()
{
DemoClass A = new DemoClass ();
DemoClass B = (DemoClass) A. Clone ();
B. intValue = 2;
Write (string. Format ("int-> [A: {0}] [B: {1}]", A. intValue, B. intValue ));
B. strValue = "2 ";
Write (string. Format ("string-> [A: {0}] [B: {1}]", A. strValue, B. strValue ));
B. pEnum = PersonEnum. EnumB;
Write (string. format ("Enum-> [A: {0}] [B: {1}]", (int). pEnum, (int) B. pEnum ));
B. pStruct. StructValue = 2;
Write (string. Format ("struct-> [A: {0}] [B: {1}]", A. pStruct. StructValue, B. pStruct. StructValue ));
B. pIntArray [0] = 2;
Write (string. format ("intArray-> [A: {0}] [B: {1}]",. pIntArray [0], B. pIntArray [0]);
B. pStringArray [0] = "2 ";
Write (string. format ("stringArray-> [A: {0}] [B: {1}]",. pStringArray [0], B. pStringArray [0]);
B. pClass. Name = "2 ";
Write (string. Format ("Class-> [A: {0}] [B: {1}]", A. pClass. Name, B. pClass. Name ));
System. Console. Read ();
}
Static void Write (string msg)
{
System. Console. WriteLine (msg );
}
Note:
We change the value of instance B and print the values of instance A and instance B to see the result.
The output is as follows:
We know from the final output:
For internal Class objects and arrays, Copy the address. [When B is changed, A is also changed]
For other built-in int/string/Enum/struct/object types, copy the value.
Finally, I tried Baidu to find the native definition of the shortest copy. If I couldn't find it, I will leave it to the readers to answer.
Next, I successfully compared the performance tests of the shortest copy and deep copy:
Add a function to DemoClass first:
Public object CloneNew ()
{
Return new DemoClass ();
}
Next, let's write a sample code comparison:
Public static void Compare ()
{
DemoClass baseClass = new DemoClass ();
DateTime start = DateTime. Now;
For (int I = 0; I <1000000; I ++)
{
DemoClass newClass = (DemoClass) baseClass. Clone ();
}
TimeSpan ts = DateTime. Now-start;
System. Console. WriteLine ("Light copy:" + ts. Ticks );
DateTime start2 = DateTime. Now;
For (int j = 0; j <1000000; j ++)
{
DemoClass newClass = (DemoClass) baseClass. CloneNew ();
}
TimeSpan ts2 = DateTime. Now-start2;
System. Console. WriteLine ("Deep copy:" + ts2.Ticks );
System. Console. Read ();
}
The final result is as follows:
It seems that it is better to directly return a new object using the shortest copy function. Similarly, some overhead of type conversion is required after an object is returned by cloning. How can this problem be solved!
Postscript:
These two questions have just caught a cold in the past two days. They are all temporary questions. Next, I will continue to write articles about the CYQ. Data lightweight Data layer path framework.