Barcode internment?

The second call to ReferenceEquals returns false. Why is the line in s4 not included? (I don't care about StringBuilder's string concatenation benefits.)

string s1 = "tom"; string s2 = "tom"; Console.Write(object.ReferenceEquals(s2, s1)); //true string s3 = "tom"; string s4 = "to"; s4 += "m"; Console.Write(object.ReferenceEquals(s3, s4)); //false 

When I do String.Intern(s4); I still get false.

Here both s3 and s4 are interned, but their links are not equal?

 string s3 = "tom"; string s4 = "to"; s4 += "m"; String.Intern(s4); Console.WriteLine(s3 == s4); //true Console.WriteLine(object.ReferenceEquals(s3, s4)); //false Console.WriteLine(string.IsInterned(s3) != null); //true (s3 is interned) Console.WriteLine(string.IsInterned(s4) != null); //true (s4 is interned) 
+8
string reference c # clr string-interning
source share
6 answers

String in s4 interned. However, when you do s4 += "m"; , you created a new string that will not be interned because its value is not a string literal, but the result of a string concatenation operation. As a result, s3 and s4 are two different string instances in two different memory locations.

For more information on string internationalization, look here , in particular for the last example. When you execute String.Intern(s4) , you do intern the string, but you still do not perform a test test for the equality between these two interned strings. The String.Intern method returns the interned string, so you will need to do this:

 string s1 = "tom"; string s2 = "tom"; Console.Write(object.ReferenceEquals(s2, s1)); //true string s3 = "tom"; string s4 = "to"; s4 += "m"; Console.Write(object.ReferenceEquals(s3, s4)); //false string s5 = String.Intern(s4); Console.Write(object.ReferenceEquals(s3, s5)); //true 
+17
source share

Lines are immutable. This means that their contents cannot be modified.

When you do s4 += "m"; internally, the CLR copies the string to another location in memory that contains the original string and the added part.

See MSDN String Link .

+3
source share

First of all, everything written so far about immutable strings is true. But there are some important things that are not written. The code

 string s1 = "tom"; string s2 = "tom"; Console.Write(object.ReferenceEquals(s2, s1)); //true 

it really displays "True", but only because of a slight compiler optimization, or like here, because the CLR ignores the attributes of the C # compiler (see "CLR through C #") and puts only one "tom" in the heap.

Secondly, you can correct the situation with the following lines:

 s3 = String.Intern(s3); s4 = String.Intern(s4); Console.Write (object.ReferenceEquals (s3, s4)); //true 

The String.Intern function computes the hash code of the string and looks for the same hash in the internal hash table. Since it finds this, it returns a reference to an existing String object. If the row does not exist in the internal hash table, a copy of the row is executed and the hash is calculated. The garbage collector does not free memory for the row because it has a hash table reference.

+2
source share

Source: https://blogs.msdn.microsoft.com/ericlippert/2009/09/28/string-interning-and-string-empty/

String interpretation is a compiler optimization method. If there are two identical string literals in one compiler, then the generated code ensures that there is only one string object (characters enclosed in double quotes) to build the entire instance of this literal.

I am from C # background, so I can explain by giving an example:

 object obj = "Int32"; string str1 = "Int32"; string str2 = typeof(int).Name; 

conclusion of the following comparisons:

 Console.WriteLine(obj == str1); // true Console.WriteLine(str1 == str2); // true Console.WriteLine(obj == str2); // false !? 

Note 1 . Objects are compared by reference.

Note2 : typeof (int). The name is evaluated by reflection, so it is not evaluated at compile time. Here, these comparisons are performed at compile time.

Analysis of the results: 1) true, because both of them contain the same literal, and therefore the generated code will have only one object referencing "Int32". See note 1 .

2) true, because the contents of both values โ€‹โ€‹are checked, which is the same.

3) FALSE because str2 and obj do not have the same literal. See Note 2 .

+2
source share

In C #, each line is a separate object and cannot be edited. You create links to them, but each line is different. The behavior is consistent and understandable.

May I suggest exploring the StringBuilder class for managing strings without creating new instances? This should be enough for everything you want to do with strings.

+1
source share

When comparing two objects, not strings, the string equality operator is not called, since this is a static method without polymorphism.

Here is the test:

 static void Test() { object o1 = "a"; object o2 = new string("a".ToCharArray()); string o3 = "a"; string o4 = new string("a".ToCharArray()); object o5 = "a"; // Compiler optimization addr(o5) = addr(o6) object o6 = "a"; string o7 = "a"; // Compiler optimization addr(o7) = addr(o8) string o8 = "a"; Console.WriteLine("Enter same text 4 times:"); object o9 = Console.ReadLine(); object o10 = Console.ReadLine(); string o11 = Console.ReadLine(); string o12 = Console.ReadLine(); Console.WriteLine("object arr o1 == o2 ? " + ( o1 == o2 ).ToString()); Console.WriteLine("string arr o3 == o4 ? " + ( o3 == o4 ).ToString()); Console.WriteLine("object const o5 == o6 ? " + ( o5 == o6 ).ToString()); Console.WriteLine("string const o7 == o8 ? " + ( o7 == o8 ).ToString()); Console.WriteLine("object cnsl o9 == o10 ? " + ( o9 == o10 ).ToString()); Console.WriteLine("string cnsl o11 == o12 ? " + ( o11 == o12 ).ToString()); Console.WriteLine("o1.Equals(o2) ? " + o1.Equals(o2).ToString()); Console.WriteLine("o3.Equals(o4) ? " + o3.Equals(o4).ToString()); Console.WriteLine("o5.Equals(o6) ? " + o5.Equals(o6).ToString()); Console.WriteLine("o7.Equals(o8) ? " + o7.Equals(o8).ToString()); Console.WriteLine("o9.Equals(o10) ? " + o9.Equals(o11).ToString()); Console.WriteLine("o11.Equals(o12) ? " + o11.Equals(o12).ToString()); } 

Results:

 object arr o1 == o2 ? False string arr o3 == o4 ? True object const o5 == o6 ? True string const o7 == o8 ? True object cnsl o9 == o10 ? False string cnsl o11 == o12 ? True o1.Equals(o2) ? True o3.Equals(o4) ? True o5.Equals(o6) ? True o7.Equals(o8) ? True o9.Equals(o10) ? True o11.Equals(o12) ? True 

https://referencesource.microsoft.com/#mscorlib/system/string.cs

+1
source share

All Articles