36

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 = "")

12
  • 6
    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, 2012 at 17:42
  • 21
    Because otherwise, you couldn't do evil things like typeof(string).GetField("Empty").SetValue(null, " "); ;) Jan 17, 2012 at 18:36
  • 1
    @MasonWheeler - The joys of reflection. For real evil, you need introspection, eh?
    – Oded
    Jan 17, 2012 at 20:09
  • 1
    @MasonWheeler, +1. Oh god, the goggles, they do nothing!]
    – Machado
    Jan 18, 2012 at 11:53
  • 1
    @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(""); } }? Jan 25, 2012 at 15:17

4 Answers 4

56

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.

3
  • 5
    +1 for being the only correct answer so far.
    – psr
    Jan 17, 2012 at 18:52
  • Some languages might not even have an empty string literal. Apparently, standard Pascal didn't.
    – dan04
    Jan 18, 2012 at 2:35
  • 2
    "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, 2012 at 5:55
13

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?
11
  • 1
    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, 2012 at 17:58
  • 37
    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.
    – user7043
    Jan 17, 2012 at 18:03
  • 9
    @delnan is absolutely right. "" / string.Empty are interned and only one object will be created.
    – Oded
    Jan 17, 2012 at 18:27
  • 13
    @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, 2012 at 19:58
  • 4
    @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. Jan 26, 2012 at 21:30
2

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 = ""; 
2
  • 2
    So your point is... ?
    – user7043
    Jan 17, 2012 at 20:34
  • 1
    The point is String.Empty is basically a constant for "". Find the author of String.cs for a deeper meaning. :)
    – Jon Raynor
    Jan 17, 2012 at 20:52
0

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.

4
  • 4
    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, 2012 at 13:50
  • 7
    @ChrisF: I can't ever reorganize the blog. That would be a breaking change, and you know how I feel about those. Jan 26, 2012 at 21:28
  • 1
    @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, 2012 at 21:35
  • 3
    @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. Jan 26, 2012 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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