C # String and shortest copy and deep copy,
1. Whether String is a value type or a reference type
MSDN explicitly states that String is a reference type rather than a value type, but it is actually a value type on the surface. Why?
Start with the following example:
//value type
Int a = 1;
Int b = a;
a = 2;
Console.WriteLine("a is {0},b is {1}", a, b);
/ / reference type
String str1 = "ab";
String str2 = str1;
Str1 = "abc";
Console.WriteLine("str1 is {0},str2 is {1}", str1, str2);
Console.Read();
Output result:
//result:
//a is 2,b is 1
//str1 is abc,str2 is ab
The running result shows that the value of str2 is still AB and does not change with the value of str1. If the string type is reference, Str1 and Str pointers point to the same memory address. If the Str content changes, Str1 should also change accordingly. In this example, the string is more of the value type. But MSDN says String is the reference type. The reason is,This is because the string object is unchangeable., Including the length and any characters in it cannot be changed.
For immutable data types, see: https://www.cnblogs.com/mushroom/p/4373951.html
Immutability of String
A string object is called an immutable (read-only), because once this object is created, the value of this object cannot be modified. Sometimes it seems that the string has been modified. Actually, A New string object will be created every time the value is changed, and the variable will point to this new object, the original object is still directed to the original object, so it will not change. This is also the cause of low string efficiency. If you change the string value frequently, use StringBuilder instead of string.
In this example, str1 = "AB" is saved in the memory. If you create another string object, its value is equal to "AB ", str2 = "AB", instead of re-allocating the memory space, it assigns the previously saved "AB" Address to the reference of str2. this confirms the result in example 2. When the value of str1 = "abc" is changed, check the memory and find that this string does not exist. Then, re-allocate the memory space and store "abc ", and assign the address to str1, while str2 still points to the address of "AB. The results in the example can be verified.
Conclusion
String is a reference type, but the compiler does some special processing on it.
Ii. Shallow copy and deep copy
Some people may explain the difference between the light copy and the deep copy in C # as follows:
The copy address of the reference type is used for copying the value type directly.
It cannot be said that it is completely wrong, but at least it is not rigorous. For example, what about the string type?
In fact, we can find the answer through practice.
First, define the following types:
Int, string, enum, struct, class, int [], string []
The Code is as follows:
//enumerate
Public enum myEnum
{ _1 = 1, _2 = 2 }
//Structure
Public struct myStruct
{
Public int _int;
Public myStruct(int i)
{ _int = i; }
}
//class
Class myClass
{
Public string _string;
Public myClass(string s)
{ _string = s; }
}
//ICloneable: Creates a new object as a copy of the current instance.
Class DemoClass : ICloneable
{
Public int _int = 1;
Public string _string = "1";
Public myEnum _enum = myEnum._1;
Public myStruct _struct = new myStruct(1);
Public myClass _class = new myClass("1");
//Array
Public int[] arrInt = new int[] { 1 };
Public string[] arrString = new string[] { "1" };
/ / Returns a new object of this instance copy
Public object Clone()
{
//MemberwiseClone: Returns a shallow copy of the current object (it is the base method of the Object object)
Return this.MemberwiseClone();
}
}
Note:
ICloneable Interface: Supports cloning, that is, creating a new instance with the same value as an existing instance.
MemberwiseClone Method: Create a superficial copy of the current System. Object.
Next, buildInstance, AndInstanceClone to generateInstance B.
Then, changeInstance BAnd observeInstanceWill the value be changed.
The Code is as follows:
Class shallow copy and deep copy
{
Static void Main(string[] args)
{
DemoClass A = new DemoClass();
/ / Create a copy of instance A --> New object instance B
DemoClass B = (DemoClass)A.Clone();
B._int = 2;
Console.WriteLine(" int \t\t A:{0} B:{1}", A._int, B._int);
B._string = "2";
Console.WriteLine(" string \t A:{0} B:{1}", A._string, B._string);
B._enum = myEnum._2;
Console.WriteLine(" enum \t\t A:{0} B:{1}", (int)A._enum, (int)B._enum);
B._struct._int = 2;
Console.WriteLine(" struct \t A:{0} B:{1}",
A._struct._int, B._struct._int);
B._class._string = "2";
Console.WriteLine(" class \t\t A:{0} B:{1}",
A._class._string, B._class._string);
B.arrInt[0] = 2;
Console.WriteLine(" intArray \t A:{0} B:{1}",
A.arrInt[0], B.arrInt[0]);
B.arrString[0] = "2";
Console.WriteLine(" stringArray \t A:{0} B:{1}",
A.arrString[0], B.arrString[0]);
Console.ReadKey();
}
}
The result is as follows:
From the final output result, we know that:
For internal Class objects and arrays, Copy an address. [When B is changed, A is also changed]
For other built-in int/string/enum/struct/object types, Copy a value.
One user said: although the string type is a reference type, in many cases. Net treats the string as a value type. I think the string type should also be processed according to the value type.
This indicates that he is not familiar with the string type.
It is certain that string must be of the reference type. Why is it a deep copy?
If you look at the source code of the string type, you will know:
// Indicates an empty string. This field is read-only. Public static readonly string Empty;
The answer is that the string type is readonly. When the value of the string type is changed, the memory address will be re-allocated.
Shallow copy: copy a new object to the object.
Definition of shortest copy-only allocates a new memory address for the value type (or string.
Deep copy: copy a new object to the object.
Definition of deep copy-allocate a new memory address for the value type, a new address for the reference type, and a new address for the internal field of the reference type.
I defined it as follows: copying a copy is not needed.
Iii. Clone () method
For example, I have a simple class:
class People
{
public int _age;
public string _name;
public People(int Age,string Name)
{
_age = Age;
_name = Name;
}
}
Common assignment statements, such:
People Mike = new People(12,"Mike");People Mike2 = Mike;
This is a light copy, sharing the same memory, similar to a pointer, that is, both the Mike2 and the Mike object point to the memory that Mike applied for when he created it.
Now I add a Clone () method for the People class:
class People
{
public int _age;
public string _name;
public People(int Age,string Name)
{
_age = Age;
_name = Name;
}
public object Clone()
{
People MySelf = new People(this._age,this._name);
return MySelf; }
}
Obviously, the object returned by calling the Clone () method is a brand new object, which is a newly instantiated object but is equal to the original object in value.
People Mike = new People(12,"Mike");
People Mike2 = Mike;
People Mike3 = Mike.Clone() as People;
The values of Mike2 and Mike3 are equal, but they are actually completely independent objects.
Mike2._name = "Jone";
// After executing the above code, Mike's _name attribute is changed, and Mike3 is unchanged.