As we all know, the string in C # Is a reference type, and the string object is stored on the stack rather than on the stack. Therefore, when a string variable is assigned to another string, two references to the same string in memory are obtained. But have you ever wondered why modifying one of the strings is not affected?
It turns out that when we assign a string variable to another string, A New String object will be created, that is, there will be two objects at this time, for example:
Class StringExc
{
Public static void Main ()
{
String s1 = "original string ";
String s2 = s1; // note that a new object is created.
Console. WriteLine ("s1 is" + s1 );
Console. WriteLine ("s2 is" + s2 );
S1 = "changed string ";
Console. WriteLine ("s1 is now" + s1 );
Console. writeline ("S2 is now" + S2 );
}
}
Output result:
S1 is original string
S2 is original string
S1 is now changed string
S2 is now original string
That is to say, changing the s1 value does not have any impact on s2, which is exactly the opposite of what we call the reference type. When s1 is initialized with the value "original string", a String object is allocated to the stack. When s2 is initialized, the reference also points to this object, so the s2 value is also "original string ". But now we need to change the s1 value, instead of replacing the original value, a new object will be allocated to the new value on the stack. The s2 variable still points to the original object, so its value has not changed.
In addition, if we look like the following:
String str1 = "abc ";
String str2 = "abc ";
When we use System. Object. Equals (str1, str2) for comparison, the return value is true. It is reasonable to say that str1 and str2 should point to different spaces, and false should be returned. The original Equals has three versions:
Public override bool equals (object );
Public bool equals (string );
Public static bool equals (string, string );
The first two instance methods call the CompareOrdinal static method internally, which contains all characters in the string. If they are equal, true is returned. The third option first checks whether the two references point to the same object. If yes, true is returned, and no more characters are compared.
In fact, CLR uses a technology called string resident.
String str1 = "abc ";
String str2 = "abc ";
During CLR initialization, an internal hash is created. The key is a string and the value is a reference to the string in the managed heap. At the beginning, the hash is empty. During JIT compiler compilation, every text constant string is searched in the hash. The "abc" string is first searched because it is not found, the compiler constructs a New String object reference pointing to "abc" in the managed heap, and then adds the "abc" String and reference pointing to this object to the hash list.
Next, find the second "abc" in the hash list. This time, the compiler does not perform any operations because the string is found, and no other text constant strings exist in the code, after the compiler task is completed, the Code starts to be executed. During execution, the CLR finds that the first statement requires a "abc" string reference. Therefore, the CLR searches for "abc" in the internal hash and finds it, in this way, the reference to the previously created String object is saved in the variable s1. When the second statement is executed, the CLR will find "abc" in the hash again ", it will still be found, and the reference pointing to the same String object will be saved in variable s2, so s1 and s2 point to the same reference, so System. object. equals (s1, s2) returns true.
In addition, C # does not allow the use of the new operator to create a String object. The Compiler reports an error.