I read Jon Skeet's quiz and I wondered why the second sample of mine won't work while the first one does.
Why does this yield true
:
object x = new string("".ToArray()); object y = new string("".ToArray()); Console.WriteLine(x == y); //true
But this one does not:
var k="k"; //string.intern(k); // doesn't help object x = new string(k.ToArray()); object y = new string(k.ToArray()); Console.WriteLine(x == y); //false
I'm using fw 4.5 with vs2010.
Luckily I also have vs2005 installed , same results :
An empty string is represented as "" . It is a character sequence of zero characters. A null string is represented by null .
A string refers to a character's sequence. Sometimes strings can be empty or NULL. The difference is that NULL is used to refer to nothing. However, an empty string is used to point to a unique string with zero length.
Languages don't contain sets, they contain strings, It's true that for any language L, we have that the empty set is a subset of L, i.e. ∅⊆L, since this is true of any set. So if this is what you're asking, then yes, that is trivially true.
Null means nothing. Its just a literal. Null is the value of reference variable. But empty string is blank.It gives the length=0 . Empty string is a blank value,means the string does not have any thing.
Here is a blog post by Eric Lippert which answers your question: String interning and String.Empty.
He's describing similar situation:
object obj = "Int32"; string str1 = "Int32"; string str2 = typeof(int).Name; Console.WriteLine(obj == str1); // true Console.WriteLine(str1 == str2); // true Console.WriteLine(obj == str2); // false !?
So the idea is, that interning does not mean you'll have only one instance of particular string
, even when it's interned. Only compile time literals are interned by default. It means that following code prints true:
var k1 = "k"; object k2 = "k"; Console.WriteLine(k1 == k2);
But, if you try to create string with "k"
content programmatically at runtime, e.g. using string(char[])
constructor, calling ToString()
on an object, using StringBuilder
, etc, you won't get interned string by default. This one prints false;
var k1 = "k"; object k2 = new string("k".ToCharArray()); Console.WriteLine(k1 == k2);
Why? Because interning strings at runtime is expensive.
There Ain't No Such Thing As A Free Lunch.
(...)
In short, it is in the general case not worth it to intern all strings.
And about different behavior with empty string:
Some versions of the .NET runtime automatically intern the empty string at runtime, some do not!
Note that interning the new strings in the second block of code does make them equal.
var k="k"; object x = string.Intern(new string(k.ToArray())); object y = string.Intern(new string(k.ToArray())); Console.WriteLine(x == y); //true
It seems like it's interning the empty strings automatically, but non-empty strings aren't interned unless they're done explicitly (or they're literal strings which are always interned).
I'm guessing that yes, empty strings are being treated as a special case and being interned automatically, probably because the check is so trivial that it doesn't add any real performance penalty (we can safely say that ANY string of length 0 is the empty string and is identical to any other empty string -- all other strings require us to look at the characters and not just the length).
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