Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can two identical strings be two separate instances in C#?

Tags:

string

c#

In C#, strings are interned. That is, if I create the string foobar and use it a second time, C# will only have one instance of the string in memory and although I will have two references, they both will be pointing to the very same string instance. This is one reason why strings are and have to be immutable in C#.

Now, my question is, whether it is possible to somehow create two identical strings so that they are not being interned, but that we end up with two different string instances in memory, with two different addresses, that contain the very same text?

If so, how?

And, is this something than can happen accidentally, or do you need to construct a scenario explicitly for this case?

And, finally: Supposed there are two separate string instances in memory with the same value, are they equal (in terms of ==)? If so, how does == work? First compare by reference, then by value, or…?

like image 860
Golo Roden Avatar asked Dec 19 '15 12:12

Golo Roden


People also ask

How to check if two strings have same characters?

To check if two strings have the same characters:Use the sorted() function to sort the two strings. Use the equality operator to compare the results. If the comparison evaluates to True , the two strings have the same characters.

How to check string not equal in c#?

In C#, Equals(String, String) is a String method. It is used to determine whether two String objects have the same value or not. Basically, it checks for equality. If both strings have the same value, it returns true otherwise returns false.

How to ignore case when Comparing strings c#?

C# String Equals Ignore Case Generally, in c# the string Equals() method will perform case-sensitive string comparison. If we want to perform case insensitive string comparison, we need to use the OrdinalIgnoreCase property and the Equals method.


2 Answers

In C#, strings are interned.

No. In C# strings are permitted to be interned. That is a very different statement.

That is, if I create the string foobar and use it a second time, C# will only have one instance of the string in memory and although I will have two references, they both will be pointing to the very same string instance

No. Again, in C# the runtime is permitted to decide that one "foobar" is the same as another and intern them, but it is not required to do so.

Of course, if you copy a reference then the reference is copied. But if you create a second string that looks the same as an earlier string, there is no requirement that it be interned.

In practice, strings are interned when they are literals:

string x = "foobar";
string y = "foobar";
// x is reference equal to y

or when they could be computed to be identical by the compiler:

string x = "foobar";
string y = "foo" + "bar";
// x is reference equal to y

Or when you explicitly tell the runtime that you want to intern a particular string. Otherwise strings are not typically interned:

string x = "foobar";
string y = "f" + x.Substring(1); 
// x and y are not reference equal
like image 97
Eric Lippert Avatar answered Oct 11 '22 12:10

Eric Lippert


Only string literals are interned. Run-time interning is expensive, so dynamically created strings are not interned (unless you intern them explicitly by calling String.Intern).

The following strings all are different instances (you can check it using object.ReferenceEquals()):

string str1 = "foo";
string str2 = "FOO".ToLower();
string str3 = new StringBuilder().Append("f").Append("oo").ToString();

The == operator is overloaded for string to compare them by value, not by reference

public static bool operator == (String a, String b) 
{
   return String.Equals(a, b);
}

When using the == operator, you have to remember that operators are not polymorphic. So if the compile-time type of both operands is string, the string overload will be used. If at least one of them is object, the reference comparison will be performed

string str1 = "foo";
string str2 = "FOO".ToLower();
object str3 = str2;
bool valueComparison = str1 == str2;     // true - the same value
bool referenceComparison = str1 == str3; // false - different instances
like image 20
Jakub Lortz Avatar answered Oct 11 '22 12:10

Jakub Lortz