Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty string as a special case?

Tags:

c#

.net

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 :

enter image description here

like image 237
Royi Namir Avatar asked Mar 03 '14 03:03

Royi Namir


People also ask

How do you represent an empty string?

An empty string is represented as "" . It is a character sequence of zero characters. A null string is represented by null .

What is the use of empty string?

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.

Can empty string be a subset of a language?

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.

What is an empty string called?

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.


2 Answers

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!

like image 163
MarcinJuraszek Avatar answered Sep 28 '22 22:09

MarcinJuraszek


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).

like image 26
BenM Avatar answered Sep 28 '22 22:09

BenM