1. We know that string is one of the most commonly used types in programming. It is used as a primitive type in C. In terms of inheritance, string directly inherits from the object. It is a reference type and is always allocated to the managed heap. However, its behavior has the value type feature, for example, you can directly assign values to an object without using the new function. As a reference type parameter of a function, operations in the function do not affect the form parameter. [Csharp] class Program {static void Main (string [] args) {public string s = "hello"; Printing (s); Console. writeLine (s) ;}} public static void Printing (string ss) {ss = "hello world"; Console. writeLine (ss);} in the code above, a string variable s is declared, and the variable s = "hello" is assigned directly ", the method s = new string ("hello") for creating reference types is not used. We use ildasm.exe to view the generated IL code. We will find that the newobj used when creating the reference type object does not appear, instead, it is a new command ldstr, which obtains a text constant from the metadata to construct a string object. CLR optimizes String type operation. Then the Printing function is called. It receives a string object. According to our understanding of the referenced type variable, the internal modification of the Printing function to the string object will affect the external string object, however, the running results are not as similar as we thought, and the external objects have not changed. This just proves that the strings mentioned above use special syntax to create objects. When calling the Printing function, the following changes occur within the Printing function: it is not difficult to understand the output of the function through the above. 2. The constant character string is constant and will not change after creation. This is a very important feature of string. Consider the following code: string s = "hello world"; Console. writeLine (s. toUpper (). substring (1, 2); Console. writeLine (s); we perform some operations on the string in the first line of the output, but these operations do not change the value of s, and the output in the second line is still hello world. In the s operation, a New string object will be created for each operation. The original s has not changed, which is the constant of the string. This feature brings some benefits to the string type and also brings some performance loss. The advantage is that the operation can be performed between multiple threads without being locked; the disadvantage is that a large number of temporary objects are generated for string operations. These objects will increase the collection of the garbage collector and affect the performance. 3. Because of the constant character of the string, a new copy is generated when it is used as a function parameter or some other copy operations, which is a great waste of memory; at the same time, string comparison is a time-consuming operation. It must compare each character at the corresponding position in the string. To solve the preceding problem, CLR maintains a hash table internally, uses the string as the key, and uses the reference of the string in the managed heap as the value. When creating a string, CLR first searches for the corresponding key in the hash table. If the key does not exist, it creates a copy of the string, store the copy in the hash table and return a reference to the copy. If there is a key that is the same as the created string, the corresponding value (string reference) is directly returned ). Strings stored in the hash table are not managed by the garbage collector. That is to say, the hash table will be released only when the program domain is detached. The CLR does not choose to retain dynamically created strings. We can use the string static method Intern to implement forced retention. The following code: [csharp] string s1 = "hello"; string s2 = "hello"; bool B = object. referenceEquals (s1, s2); Console. writeLine ("Does s1 and s2 share the same reference:" + B); string s3 = "hello world"; string s4 = s1 + "world"; bool b1 = object. referenceEquals (s3, s4); Console. writeLine ("s3 and s4 have the same reference:" + b1); Console. writeLine ("Does s3 and s4 have the same value:" + s3.Equals (s4); string s5 = string. intern (s4); b1 = object. referenceEquals (s3, s5); Co Nsole. writeLine ("Does s3 and s5 have the same reference:" + b1); the output is as follows: 1. Does s2 have the same reference: True s3 and s4 have the same reference: false s3 and s4 have the same value: True s3 and s5 have the same reference: True 4 when the string pool compiles the source code, the text constant is embedded into the metadata, this will cause the same string to be embedded into the metadata multiple times, increasing the capacity of the generation module. To solve this problem, after the C # compiler writes the string once, the same code appears in the following code, only a reference to the Written string, effectively ensuring the capacity of the generation module, this is the string pool technology.