88

Recently a colleague at work told me not to use string.Empty when setting a string variable but use null as it pollutes the stack?

He says don't do

string myString=string.Empty; but do string mystring=null;

Does it really matter? I know string is an object so it sort of makes sense.

I know is a silly question but what is your view?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
user712923
  • 1,515
  • 2
  • 16
  • 19
  • 1
    I'm not entirely sure why you'd do either... can you give slightly more of the code you were discussing as an example? – stusmith Jul 14 '11 at 07:39
  • there is no code.I asked my collegue to look at something that I was debugging and he said as a general rule "dont use string.empty" set it to null as it goes on the stack.Personally I have always used string.Empty as the time it came out was supposed to be the right thing to use rather than "". – user712923 Jul 14 '11 at 07:41
  • Also see: [In C#, should I use string.Empty or String.Empty or "" ?](http://stackoverflow.com/questions/263191/in-c-should-i-use-string-empty-or-string-empty-or) – Cody Gray - on strike Jul 14 '11 at 07:44
  • What I mean is... `string.Empty`, `""`, and `null` are all constant values, but they're all 'simple' enough that I can't see why you'd assign one to a variable. If you need to capture an `out` variable, why not just use `string myString;`? – stusmith Jul 14 '11 at 07:44
  • 9
    These days, arguments on topics such as this that are not focused on readability and semantics and focus on absurd micro-optimizations are weak, at best. Use whichever one means the correct thing for your given context. (e.g., If you know someone does not have a middle name, you use `String.Empty`; if you don't know whether or not someone has a middle name you use `null`). Then, once you have the right meaning, write the code in a way that is clearly correct and easily maintained. – jason Jul 14 '11 at 12:31
  • @jason, if one has no middle name, why wouldn't use `null` to indicate "no middle name"? I interpret an empty string here as "has a middle name, and is empty", which sounds strange. – OfirD Jul 16 '19 at 16:19

5 Answers5

120

null and Empty are very different, and I don't suggest arbitrarily switching between them. But neither has any extra "cost", since Empty is a single fixed reference (you can use it any number of times).

There is no "pollution" on the stack caused by a ldsfld - that concern is.... crazy. Loading a null is arguably marginally cheaper, but could cause null-reference exceptions if you aren't careful about checking the value.

Personally, I use neither... If I want an empty string I use "" - simple and obvious. Interning means this also has no per-usage overhead.


At the IL level, the difference here between "" and Empty is just ldstr vs ldsfld - but both give the same single interned string reference. Furthermore, in more recent .NET versions the JIT has direct interception of these, yielding the empty string reference without actually doing a static field lookup. Basically, there is exactly no reason to care either way, except readability. I just use "".

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • @Marc +1 for _null and Empty are very different_. Not differentiating between the two results in the abominable `if (str != null && !str.equals("")` – Miserable Variable Jul 14 '11 at 07:41
  • thanks for your answer.The reason I ask is because the tone used by my collegue when talking was more of a telling off one rather than an informative one,so I said to myself let me ask on stackoverflow. – user712923 Jul 14 '11 at 07:46
  • 5
    @user712923 if he comes back with any concrete concerns, I'd love to hear them – Marc Gravell Jul 14 '11 at 08:00
  • 5
    @Marc: ASAIK "" creates an object where string.Empty is not.. check [this](http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx) and [this](http://kossovsky.net/index.php/2009/06/string-empty-versus-empty-quotes/). It have something to do with string intern pool.... – Jalal Said Jul 14 '11 at 10:02
  • @Jalal - the difference is slight, and may even change between implementations. Either way, it isn't a string instance per usage – Marc Gravell Jul 14 '11 at 11:29
  • 7
    @Hemal: [String.IsNullOrEmpty()](http://msdn.microsoft.com/en-us/library/system.string.isnullorempty.aspx) – Vinko Vrsalovic Jul 14 '11 at 11:49
  • 1
    +1 for using `""` instead of a six times longer boilerplate code. Whoever advocated this nonsense?! @Jalal That Brad Abrams posting is seriously outdated and if the compiler *still* doesn’t optimise those two codes to do the same, then shame on Microsoft! But it’s not our job to fix their work. And in fact, we don’t need to: In the second link, Lasse (in the comments) has compared the assembly outputs of comparing with either variant: they are identical. – Konrad Rudolph Jul 14 '11 at 14:49
  • 1
    @Konrad: One example is what is happening when concatenate constant strings: the string class uses intern pool so when you make a new string, the class check if the string is already in the pool and then if not added it to the pool.. Because of that when `""` it will search the entire pool to check if it already there or not, and that is way when using the `string.Empty;` it will use that _predefined_ value and the search will no longer exists. the class also exposeed this methods: `string.Intern/IsInterned` check [this](http://community.bartdesmet.net/blogs/bart/archive/2006/09/27/4472.aspx) – Jalal Said Jul 14 '11 at 15:18
  • @Jalal This article is *also* completely outdated, and I doubt much of it still applied now. It’s a trivial optimization for the compiler/JIT to intern `""`. Furthermore, checking the string interning pool is a very cheap operation, no “search[ing of] the entire pool” happens. – Konrad Rudolph Jul 14 '11 at 15:22
  • @Konrad: it is not a big deal after all, really, but for me it is just that not every time create new `""` where I have a static variable out there. Imagine you have a static field in Image class called `Image.Empty` then I will certainly not use `new Image(1, 1)` for example.. it is also not about how many _characters_ the code is.. – Jalal Said Jul 14 '11 at 15:37
  • 1
    @Jalal Notice how I’m not advocating using `new String(new char[]{})` so your comparison doesn’t really work. Furthermore: “it is also not about how many characters the code is” – no: in a way, it *is*. Unnecessary code leads to visual clutter, reducing legibility. – Konrad Rudolph Jul 14 '11 at 15:50
  • @Jalal it doesnt matter how many times I use the literal `""` in an assembly - that is one single string instance. Any comparison to `new Image(...)` is meaningless – Marc Gravell Jul 14 '11 at 17:26
  • @Marc: The `Image.Empty` example here just to demonstrate the code reusability. when I have a static field that already declared there I will use it. – Jalal Said Jul 14 '11 at 17:37
  • @Vinko see other explanations here why differentiating between null and empty string is a good thing. – Miserable Variable Jul 14 '11 at 18:22
  • @Jalal even if it (subjectively, perhaps) makes the code *less readable and obvious*, with no extra efficiency to warrant it? – Marc Gravell Jul 14 '11 at 18:27
  • @Hemal I was specifically referring to your abonimable code snippet. – Vinko Vrsalovic Jul 14 '11 at 20:43
  • @Vinko understood. I had meant that the need for such checks is abominable, not the code itself. Speaking as one who has to daily use his handwritten `StringUtils.isNullOrEmpty(String)` (in Java) :) – Miserable Variable Jul 15 '11 at 04:37
41

It doesn't 'pollute the stack', there's no technical reason but there is a big difference between setting a variable to a reference to an object (even if it's an empty string) and null. They are not the same thing and should be used in different ways.

null should be used to indicate the absence of data, string.Empty (or "") to indicate the presence of data, in fact some empty text. Is there a specific case where you're not sure what is the most appropriate?

Edit, added examples:

  • You might use string.Empty as the default postfix for a person's name (most people don't have PhD for example)

  • You might use null for a configuration option that wasn't specified in the config file. In this case, string.Empty would be used if the config option was present, but the desired configured value was an empty string.

Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144
  • I never thought that way ,I have to admit.Given what you just said ,do you mind to give me an example.I know your explanation is self explanatory but still... thanks – user712923 Jul 14 '11 at 07:43
  • 2
    Well, the only reason to choose one or the other is based on the place you would use it. I.e. use `string.Empty` or `""` when you want to use an empty string and `null` when you want to indicate there is no data. You might use `string.Empty` as the default postfix for a person's name (most people don't have PhD for example) - and `null` for a configuration option that wasn't specified in the config file. In that second case, `string.Empty` would be used if the config option was present, but the desired configured value was an empty string. – Kieren Johnstone Jul 14 '11 at 07:48
  • @Kieren Johnstone, if one has no postfix name, why wouldn't use `null` to indicate "no postfix"? – OfirD Jul 16 '19 at 16:16
9

They are different as others already answered.

static void Main(string[] args)
{
    string s1 = null;
    string s2 = string.Empty;
    string s3 = "";
    Console.WriteLine(s1 == s2);
    Console.WriteLine(s1 == s3);
    Console.WriteLine(s2 == s3);
}

Results:

  1. false - since null is different from string.empty
  2. false - since null is different from ""
  3. true - since "" is same as string.empty

The problem with managing empty string vs. null strings is becoming a problem when you need to either persist it into a flat file or transfer it through communications, So I find it might be useful for other who visit this page to give a nice solution to that particular problem.

For the purpose of saving strings into a file or communications:
you will probably want to convert the string into bytes.
a good practice I recommend is to add 2 segments of header bytes to your converted string.

segment 1 - meta info which is stored in 1 byte and describes the length of the the next segment.

segment 2 - holds the length of the string to be saved.

example:
string "abcd" - to simplify I'll convert it using ASCII encoder and will get {65,66,67,68}.
calculate segment 2 will yield 4 - so 4 bytes are the length of the converted string.
calculate segment 1 will yield 1 - as just 1 byte was used to hold the length information of the converted string information (which was 4, i.e. if it was 260 I would get 2)

The new stripe of bytes will now be {1,4,65,66,67,68} which can be saved to a file.

The benefit in respect to the subject is that if I had an empty string to save I would get from conversion an empty array of bytes in the length of 0 and after calculating the segments I will end up having {1,0} which can be saved and later on loaded and interpreted back into an empty string. On the other hand if I had null value in my string I would end up having just {0} as my byte array to save and again when loaded can be interpreted back to null.

There are more benefits such as knowing what the size to be loaded or accumulate if you jag multiple strings.

Back to the subject - it will.. well kind of pollute the stack as the same principals described are being used by any system to differentiate nulls from empty.. so yes string.Empty does take more memory than null, though I wouldn't call it pollution.. it just 1 more byte.

Qaz
  • 45
  • 1
  • 4
G.Y
  • 6,042
  • 2
  • 37
  • 54
0

It's been answered to death, but null means no value, not initialized. string.Empty means "" (a blank string) as it is stated on MSDN.

The safest way to check for an empty or null string is using string.IsNullOrEmpty.

Karolis Koncevičius
  • 9,417
  • 9
  • 56
  • 89
-3

FWIW, I found that mixing "" and String.Empty doesn't work:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"

var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

In particular, if you use $.trim to get the value of an empty DOM input field, then compare it to String.Empty, you get false. Not sure why that is, but there you go. I now just use "" everywhere for consistency.

DaveShaw
  • 52,123
  • 16
  • 112
  • 141