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 = ""
)
4 Answers
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.
-
5
-
-
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.– detlyJan 24, 2012 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 acrossfoo = ""
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?
-
1It would seem to be an odd behavior for it to keep two identical strings in memory. Is that in fact what is done?– RigJan 17, 2012 at 17:58
-
37In 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.– user7043Jan 17, 2012 at 18:03
-
9@delnan is absolutely right.
""
/string.Empty
are interned and only one object will be created.– OdedJan 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.– OdedJan 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
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 = "";
-
2So your point is... ?– user7043Jan 17, 2012 at 20:34
-
1The point is String.Empty is basically a constant for "". Find the author of String.cs for a deeper meaning. :) Jan 17, 2012 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.
-
4Link 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
typeof(string).GetField("Empty").SetValue(null, " ");
;)public static string Empty { get { return string.Intern(""); } }
?