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…?
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With