138

I have always initialized my strings to NULL, with the thinking that NULL means the absence of a value and "" or String.Empty is a valid value. I have seen more examples lately of code where String.Empty is considered the default value or represents no value. This strikes me as odd, with the newly added nullable types in c# it seems like we are taking strides backwards with strings by not using the NULL to represent 'No Value'.

What do you use as the default initializer and why?

Edit: Based on the answers I futher my further thoughts

  1. Avoiding error handling If the value shouldn't be null, why did it get set to NULL in the first place? Perhaps it would be better to identify the error at the place where it occurs rather than cover it up through out the rest of your codebase?

  2. Avoiding null checks If you are tired of doing null checks in code, wouldn't it be better to abstract the null checks? Perhaps wrap (or extend!) the string methods to make them NULL safe? What happens if you constantly use String.Empty and a null happens to work it's way into your system, do you start adding NULL checks anyways?

I can't help but return to the opinion that it is laziness. Any DBA would slap you nine ways to silly if you used '' instead of null in his\her database. I think the same principles apply in programming and there should be somebody to smack those upside the head who use String.Empty rather than NULL to represent no value.

Related Questions

Community
  • 1
  • 1
vfilby
  • 9,938
  • 9
  • 49
  • 62
  • 'The Sane'? Mustn't be a Dana I know. – vfilby Nov 05 '08 at 17:27
  • @Joel, I am amazed by how many people have no clue about Zim or G.I.R. I am also amazed at some of my friends who find it repulsive. Not saying it is pure goodness, but there are awesome nuggets of humour in there. – vfilby Nov 05 '08 at 17:36
  • I know, but sometimes it's fun to pretend otherwise. – Dana the Sane Nov 05 '08 at 17:48
  • 1
    I run into this problem on MVC form collections or session variables a lot, i found the most useful thing was to convert null to String.Empty with the ?? shorthand, and then apply whatever string operation required. eg. (item ?? String.Empty).Trim().ToUpper() – sonjz Jan 15 '13 at 19:57
  • 4
    this is not constructive?? – nawfal Mar 31 '13 at 10:03

17 Answers17

116

+1 for distinguishing between "empty" and NULL. I agree that "empty" should mean "valid, but blank" and "NULL" should mean "invalid."

So I'd answer your question like this:

empty when I want a valid default value that may or may not be changed, for example, a user's middle name.

NULL when it is an error if the ensuing code does not set the value explicitly.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150
  • 11
    Distinguishing between NULL and empty is great when there is actually a difference between the two. There are many cases, though, where there is not a difference, and thus having two ways of representing the same thing is a liability. – Greg Smalter Nov 05 '08 at 17:27
  • 6
    @Greg: While I agree that variety has the potential for confusion, it can also be a great asset. The simple, consistent convention of writing "" or NULL to differentiate between valid and invalid values will make your code easier to understand. This is why I always test booleans with "if (var)," pointers with "if (var != NULL)" and integers with "if (var != 0)" -- they all mean the same thing to the compiler, but they carry additional information that helps the poor developer who maintains my code. – Adam Liss Jan 30 '10 at 19:50
  • 1
    @AdamLiss To Greg's point about two different ways to represent the same thing as a liability, you subscribed to the idea that NULL or Empty represents two simple conditions: valid and invalid. Though I have commonly seen NULL to represent a property that has not yet been set by a user. For example, fields in a user's profile. NULL can represent that the user has not yet filled in this specific information where IsEmpty specifically represents the actions of where a user has filled in that information at one point and then came back to erase it. NULL can represent that a property or – 8protons Jul 29 '21 at 15:38
  • object never existed, or does not yet exist, and that may be a totally *valid* scenario. – 8protons Jul 29 '21 at 15:40
32

According to MSDN:

By initializing strings with the Empty value instead of null, you can reduce the chances of a NullReferenceException occurring.

Always using IsNullOrEmpty() is good practice nevertheless.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 47
    Just because you're reducing the chances of the exception doesn't mean that the exception shouldn't be happening. If your code depends on a value being there, it should throw an exception! – rmeador Nov 05 '08 at 17:23
  • 1
    Sure, no argument there. OTOH, if you are just appending strings together... I think it depends on coding style, experience and the situation. – Tomalak Nov 05 '08 at 17:33
  • This is mainly what I use distinguish which to use also. – PositiveGuy Jun 15 '10 at 15:30
  • 3
    Don't forget [IsNullOrWhiteSpace()](http://msdn.microsoft.com/en-us/library/system.string.isnullorwhitespace.aspx) for .NET framework 4+ – Paul C Sep 09 '13 at 12:45
14

Why do you want your string to be initialized at all? You don't have to initialize a variable when you declare one, and IMO, you should only do so when the value you are assigning is valid in the context of the code block.

I see this a lot:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else
{
  name = "bar";
}

return name;

Not initializing to null would be just as effective. Furthermore, most often you want a value to be assigned. By initializing to null, you can potentially miss code paths that don't assign a value. Like so:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else if (othercondition)
{
  name = "bar";
}

return name; //returns null when condition and othercondition are false

When you don't initialize to null, the compiler will generate an error saying that not all code paths assign a value. Of course, this is a very simple example...

Matthijs

  • 1
    In Visual Studio, which I believe almost every C# programmer uses, your second situation (without the `= null`) would generate a warning, for exactly the reason you stated - it doesn't matter whether the default value of a string is null. if you don't guarantee an assignment through every code path, the IDE (and/or I suppose the underlying compiler[?]) will generate a warning. Though warnings will not prevent compilation, they are still there - leaving ones that are easily solved can help to obfuscate others that may warrant the programmer's attention – Code Jockey Feb 04 '16 at 15:37
  • to my knowledge, the first situation will be perfectly happy without initialization of `name` to `null` (no warnings), because every code path assigns a value to `name` - no need to initialize there at all – Code Jockey Feb 04 '16 at 15:39
9

For most software that isn't actually string-processing software, program logic ought not to depend on the content of string variables. Whenever I see something like this in a program:

if (s == "value")

I get a bad feeling. Why is there a string literal in this method? What's setting s? Does it know that logic depends on the value of the string? Does it know that it has to be lower case to work? Should I be fixing this by changing it to use String.Compare? Should I be creating an Enum and parsing into it?

From this perspective, one gets to a philosophy of code that's pretty simple: you avoid examining a string's contents wherever possible. Comparing a string to String.Empty is really just a special case of comparing it to a literal: it's something to avoid doing unless you really have to.

Knowing this, I don't blink when I see something like this in our code base:

string msg = Validate(item);
if (msg != null)
{
   DisplayErrorMessage(msg);
   return;
}

I know that Validate would never return String.Empty, because we write better code than that.

Of course, the rest of the world doesn't work like this. When your program is dealing with user input, databases, files, and so on, you have to account for other philosophies. There, it's the job of your code to impose order on chaos. Part of that order is knowing when an empty string should mean String.Empty and when it should mean null.

(Just to make sure I wasn't talking out of my ass, I just searched our codebase for `String.IsNullOrEmpty'. All 54 occurrences of it are in methods that process user input, return values from Python scripts, examine values retrieved from external APIs, etc.)

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
6

This is actually a gaping hole in the C# language. There is no way to define a string that cannot be null. This causes problems as simple as the one you are describing, which forces programmers to make a decision they shouldn't have to make, since in many cases NULL and String.Empty mean the same thing. That, in turn, can later force other programmers to have to handle both NULL and String.Empty, which is annoying.

A bigger problem is that databases allow you to define fields that map to a C# string, but database fields can be defined as NOT NULL. So, there is no way to accurately represent, say, a varchar( 100 ) NOT NULL field in SQL Server using a C# type.

Other languages, such as Spec #, do allow this.

In my opinion, C#'s inability to define a string that doesn't allow null is just as bad as its previous inability to define an int that does allow null.

To completely answer your question: I always use empty string for default initialization because it is more similar to how database data types work. (Edit: This statement was very unclear. It should read "I use empty string for default initialization when NULL is a superfluous state, much in the same way I set up a database column as NOT NULL if NULL would be a superfluous state. Similarly, many of my DB columns are set up as NOT NULL, so when I bring those into a C# string, the string will be empty or have a value, but will never be NULL. In other words, I only initialize a string to NULL if null has a meaning that is distinct from the meaning of String.Empty, and I find that case to be less than common (but people here have given legitimate examples of this case).")

Greg Smalter
  • 6,571
  • 9
  • 42
  • 63
  • Using String.Empty is only similar to *one* of the ways that a database string is defined. Using null to represent no value is much more congruent with a null nvarchar. I think any DBA worth their salt would slap you nine ways to silly if you used '' to represent no value. – vfilby Nov 06 '08 at 02:20
  • Actually, Greg, you've got it the wrong way round. It's the non-nullable value types that least "how database types work" because they cannot ever hold a null, and thus cannot ever map to a nullable column. In contract, any string can map to any varchar column. – Tor Haugen Nov 06 '08 at 02:40
  • You're right, my last assertion was not clear enough. Most times, my database columns are NOT NULL (because there would be no difference bewteen the meaning of empty string and NULL), so I attempt to keep my strings similar by never storing null in them, and that is what I meant. – Greg Smalter Nov 06 '08 at 14:34
5

It depends.

Do you need to be able to tell if the value is missing (is it possible for it to not be defined)?

Is the empty string a valid value for the usage of that string?

If you answered "yes" to both, then you'll want to use null. Otherwise you can't tell the difference between "no value" and "empty string".

If you don't need to know if there's no value then the empty string is probably safer, as it allows you to skip null checks wherever you use it.

Herms
  • 37,540
  • 12
  • 78
  • 101
4

seems like this is a special case of the http://en.wikipedia.org/wiki/Null_Object_pattern

Ray Tayek
  • 9,841
  • 8
  • 50
  • 90
3

I either set it to "" or null - I always check by using String.IsNullOrEmpty, so either is fine.

But the inner geek in me says I should set it to null before I have a proper value for it...

Surgical Coder
  • 1,086
  • 1
  • 16
  • 25
3

I always declare string with string.empty;

Ervin Ter
  • 1,113
  • 3
  • 11
  • 17
2

Is it possible that this is an error avoidance technique (advisable or not..)? Since "" is still a string, you would be able to call string functions on it that would result in an exception if it was NULL?

Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
  • 1
    That is the excuse I normally hear, just sounds like laziness. "I don't want to bother checking this value so I am going to take a shortcut" is how it seems to me. – vfilby Nov 05 '08 at 17:28
  • Yeah, I'm not disagreeing. There might be some situations where reducing the amount of error checking code is nice, but function calls that have no effect aren't the greatest either.. – Dana the Sane Nov 05 '08 at 17:45
2

I always initialise them as NULL.

I always use string.IsNullOrEmpty(someString) to check it's value.

Simple.

Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
1

It depends on the situation. In most cases I use String.Empty because I don't want to be doing null checks every time I attempt to use a string. It makes the code a lot simpler and you are less likely to introduce unwanted NullReferenceException crashes.

I only set the string to null when I need to know if it has been set or not and where an empty string is something valid to set it to. In practice, I find these situations rare.

Rob Prouse
  • 22,161
  • 4
  • 69
  • 89
1

An empty string is a value (a piece of text which, incidentally, happens not to contain any letters). Null signifies no-value.

I initialize variables to null when I wish to indicate that they do not point to or contain actual values - when the intent is for no-value.

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
1

Reiterating Tomalak response, keep in mind that when you assign a string variable to an initial value of null, your variable is no longer a string object; same with any object in C#. So, if you attempt to access any methods or properties for your variable and you are assuming it is a string object, you will get the NullReferenceException exception.

1

Null should only be used in cases where a value is optional. If the value is not optional (like 'Name' or 'Address'), then the value should never be null. This applies to databases as well as POCOs and the user interface. Null means "this value is optional, and is currently absent."

If your field is not optional, then you should initialize it as the empty string. To initialize it as null would place your object into an invalid state (invalid by your own data model).

Personally I would rather strings to not be nullable by default, but instead only nullable if we declare a "string?". Although perhaps this not feasible or logical at a deeper level; not sure.

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
0

Strings aren't value types, and never will be ;-)

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63
0

I think there's no reason not to use null for an unassigned (or at this place in a program flow not occurring) value. If you want to distinguish, there's ==null. If you just want to check for a certain value and don't care whether it's null or something different, String.Equals("XXX",MyStringVar) does just fine.

Volker
  • 1,753
  • 2
  • 18
  • 28