Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Why was the property string foo = string.Empty included in the BCL? It seems more verbose and no clearer than just using an empty string (string foo = "")

share|improve this question
Nitpick: It is not part of the language. It is part of the BCL. VB.NET and F# can use it, as well as every other .NET language. – Oded Jan 17 '12 at 17:42
Because otherwise, you couldn't do evil things like typeof(string).GetField("Empty").SetValue(null, " "); ;) – Mason Wheeler Jan 17 '12 at 18:36
@MasonWheeler - The joys of reflection. For real evil, you need introspection, eh? – Oded Jan 17 '12 at 20:09
@MasonWheeler, +1. Oh god, the goggles, they do nothing!] – Machado Jan 18 '12 at 11:53
@MasonWheeler That is pure, distilled evil. I love this. Question if you're interested: wouldn't it be safer (and decently performant) to have written it as public static string Empty { get { return string.Intern(""); } }? – Jesse C. Slicer Jan 25 '12 at 15:17
up vote 53 down vote accepted

I can only assume here:

string.Empty has been defined for explicitness - when initializing a string, it may not be clear from context that "" was indeed explicitly meant as an initializer (instead of null or say " " or just as a place holder during testing). Using string.Empty is a definite answer to that sort of conundrum.

It may also be a throwback to C - an empty string in C is not an empty string. It is a character array whose first character is null (hence, empty), which is not the same as C#. My point here being that in different languages you would represent an empty string in different ways (and they may have different meanings) - having a string.Empty precludes such ambiguity.

As opposed to what others say about multiple objects - this is not a problem as any string literal will get interned on compilation. This includes the value of string.Empty - "". Any time either of these are repeated in code, the object will be retrieved from the intern pool. This is true per app domain.

share|improve this answer
+1 for being the only correct answer so far. – psr Jan 17 '12 at 18:52
Some languages might not even have an empty string literal. Apparently, standard Pascal didn't. – dan04 Jan 18 '12 at 2:35
"an empty string in C is not an empty string" — but still, if you write "", you get {'\0'}, so there would be no difference between an empty string literal and some other roundabout way of defining it. – detly Jan 24 '12 at 5:55

I'm not 100% sure of the sources where I learned these, but some of the points for using it include:

  • Each string in a .NET assembly is unique, so having

    string foo = "";
    string bar = "";

    results in 2 strings in the output assembly since strings are immutable. Having both reference string.Empty reduces assembly size.

  • Explicitness. When you come across string.Empty the intent is clear that it's supposed to be an empty string. But if you come across foo = "" did the programmer remove the contents of the string while testing and forget to add it back, or is it supposed to be that way?
share|improve this answer
It would seem to be an odd behavior for it to keep two identical strings in memory. Is that in fact what is done? – Rig Jan 17 '12 at 17:58
In fact, the opposite is done - it's called string interning (more precisely, interning of literals). I know for sure it's done in Java and Python, and I'm pretty sure it's the case in .NET languages too. Of course, it can only happen at the scope of a single translation unit, so unless the dynamic loader unifies such data, you may end up with one empty string per program file. Still not terribly much. – delnan Jan 17 '12 at 18:03
@delnan is absolutely right. "" / string.Empty are interned and only one object will be created. – Oded Jan 17 '12 at 18:27
@Andy - All string literals are interned in .NET. Not all strings. Programmatically created strings do not get interned by default. See String.Intern on MSDN. – Oded Jan 17 '12 at 19:58
@Oded et alia: Actually none of you are exactly right. First, literals are interned within an assembly but not necessarily across assemblies. Second, whether or not the empty string is interned across assemblies is an implementation detail; some versions of the CLR do and some do not. There's a link to my article about this fact in one of the other answers; see it for the details. – Eric Lippert Jan 26 '12 at 21:30

No object will be created for string.Empty. Using "" will create an object that will most likely come from the string intern pool.

In the past, people have run tests and String.Empty comes out slightly faster, but its a micro-optimization.

String.Empty is this:

//The Empty constant holds the empty string value.   
//We need to call the String constructor so that the compiler doesn't mark 
//this as a literal.   
//Marking this as a literal would mean that it doesn't show up as a field 
//which we can access from native.  
public static readonly String Empty = ""; 
share|improve this answer
So your point is... ? – delnan Jan 17 '12 at 20:34
The point is String.Empty is basically a constant for "". Find the author of String.cs for a deeper meaning. :) – Jon Raynor Jan 17 '12 at 20:52

It is a matter of optimization of memory consumption and an optimization of string comparison. Every time you're using an empty string in your application, you are allocating a string object containing 0 characters. As for string comparison it can be done by comparing references (pointers) instead of character by character, which is a faster even for empty strings.

If you are using many times the same string in your application you can use the same kind of mechanism by calling String.Intern() with your string. But if you are using each string only once, then you'll only use more memory.

So String.Empty is only a special case optimization which is worth to do for most .Net applications, that's why it was integrated in the BCL.

For more detail on this subject I strongly recommend reading Eric Lippert's blog post.

You should also take a look at this documentation referenced by his blog post.

share|improve this answer
Link only answers don't make good answers. If Eric ever reorganises his blog this answer will become useless. Please summarise the post here so we have all the information to hand. – ChrisF Jan 24 '12 at 13:50
@ChrisF: I can't ever reorganize the blog. That would be a breaking change, and you know how I feel about those. – Eric Lippert Jan 26 '12 at 21:28
@EricLippert - I realise that you'd never do that, however, link only answers aren't good answers and we need to encourage people to realise that. – ChrisF Jan 26 '12 at 21:35
@EricLippert It's not just about ephemeral links. It's also about politeness to readers here, there should be at least enough content directly in the answer so that readers can form an opinion as to whether to follow the link. And the answer should make sense even in an offline copy of SE. – Gilles Jan 26 '12 at 21:39

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.