Cannot use String.Empty as a default value for an optional parameter

46,354

Solution 1

As of the C# 2.0 compiler, there is very little point to String.Empty anyway, and in fact in many cases it's a pessimisation, since the compiler can inline some references to "" but can't do the same with String.Empty.

In C# 1.1 it was useful to avoid creating lots of independent objects all containing the empty string, but those days are gone. "" works just fine.

Solution 2

There's nothing to stop you from defining your own constant for the empty string if you really want to use it as an optional parameter value:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[As an aside, one reason to prefer String.Empty over "" in general, that hasn't been mentioned in the other answers, is that there are various Unicode characters (zero-width joiners, etc.) that are effectively invisible to the naked eye. So something that looks like "" isn't necessarily the empty string, whereas with String.Empty you know exactly what you're using. I recognise this isn't a common source of bugs, but it is possible.]

Solution 3

From the original question:

I thought that we would use it to be sure that we have a system-independent means of referring to the empty string.

In what way can the empty string vary from system to system? It's always a string with no characters! I'd be really scared if I ever found an implementation where string.Empty == "" returned false :) This is not the same as something like Environment.NewLine.

From Counter Terrorist's bounty post:

I want String.Empty can be used as a default parameter in the next C# release. :D

Well that's certainly not going to happen.

While I would personally have liked a very different defaulting mechanism too, the way optional parameters work has been in .NET since the start - and it always means embedding a constant into the metadata, so that the calling code can copy that constant into the call site if no corresponding argument is provided.

With string.Empty it's really pointless - using "" will do what you want; is it that painful to use the string literal? (I use the literal everywhere - I never use string.Empty - but that's a different argument.)

That's what surprises me about this question - the complaint revolves around something which doesn't actually cause a real problem. It's for more important in cases where you want the default to be computed at execution time because it might actually vary. For example, I could imagine cases where you want to be able to call a method with a DateTime parameter and have it default to "the current time". At the moment, the only vaguely elegant workaround I know for that is:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... but that's not always appropriate.

In conclusion:

  • I very much doubt that this will ever be part of C#
  • For string.Empty it's pointless anyway
  • For other values which really don't always have the same value, it really can be a pain

Solution 4

I never use string.Empty, I can't see the point of it. Maybe it makes it easier for people that are really new to programming, but I doubt it's useful even for that.

Solution 5

I think the idea behind string.Empty is it enhances readability. It is not like newline where there is any difference between how it is represented on different platforms. It's ashame it can't be used in a default parameter. However, it will not cause any issues if you port between Windows and something like Mono on Linux.

Share:
46,354
Mikeyg36
Author by

Mikeyg36

Updated on July 15, 2020

Comments

  • Mikeyg36
    Mikeyg36 almost 4 years

    I am reading Effective C# by Bill Wagner. In Item 14 - Minimize Duplicate Initialization Logic, he shows the following example of using the new optional parameters feature in a constructor:

    public MyClass(int initialCount = 0, string name = "")

    Notice that he used "" instead of string.Empty.
    He comments:

    You'll note [in an example above] that the second constructor specified "" for the default value on the name parameter, rather than the more customary string.Empty. That's because string.Empty is not a compile-time constant. It is a static property defined in the string class. Because it is not a compile constant, you cannot use it for the default value for a parameter.

    If we cannot use the string.Empty static in all situations, then doesn't that defeat the purpose of it? I thought that we would use it to be sure that we have a system-independent means of referring to the empty string. Is my understanding wrong? Thanks.

    UPDATE
    Just a follow up comment. According to MSDN:

    Each optional parameter has a default value as part of its definition. If no argument is sent for that parameter, the default value is used. Default values must be constants.

    Then we aren't be able to use System.Environment.NewLine either, or use newly instantiated objects as default values. I haven't used VS2010 yet, and this is disappointing!

  • Jon Skeet
    Jon Skeet about 14 years
    Even in .NET 1.1 it wouldn't create "lots" of independent objects. I can't remember the details of the differences between 1.1 and 2.0 in this respect, but it's not like string literal interning was only introduced in 2.0.
  • Greg
    Greg about 14 years
    Maybe it prevents confusing "" and " ", but I can't say that " " is all that common.
  • Hans Olsson
    Hans Olsson about 14 years
    I'd suggest that anyone that can't tell the difference between those needs either better glasses or to lower the resolution of their screen. I've got bad eyesight and I can't recall ever making that mistake (and I do have to work with a lot of code that contains both of that).
  • Andy Mortimer
    Andy Mortimer about 14 years
    Thanks for the clarification. I've had a look around and I haven't found a good summary of the changes in C# 2.0, although I'm sure I've read one previously. I did find a StackOverflow answer from 2008 with some links to more technical information. stackoverflow.com/questions/151472/…
  • xximjasonxx
    xximjasonxx about 14 years
    I'll give this a nod, though I dislike saying there is little point to string.Empty as I use it quite heavily. I find it just looks cleaner, though that is my personal opinion. There are many places string.Empty cannot be use, and I have no problem using "" in those cases
  • Tim Goodman
    Tim Goodman about 14 years
    I think you're probably right that the point is that some people consider String.Empty more readable . . . personally though, I think that's a little nutty. "" is probably the most common string there is and everyone has seen it a billion times, so how is it unreadable? String.Empty is about as useful as if there were an Int32.Zero.
  • tames
    tames about 14 years
    I've used string.Empty only because it was the "recommended" thing to do, but I never really liked it. The literal "" seemed straight-forward and clear and with string interning, it's economical too.
  • NotMe
    NotMe about 13 years
    I've found that it's much easier to quickly identify an empty string with String.Empty than looking twice at "" to ensure it didn't have an apostrophe or something like that hidden in it. +1 for the explanation though.
  • MutantNinjaCodeMonkey
    MutantNinjaCodeMonkey about 12 years
    +1 Chris. Also in VS, you really can't do a search on usages of "" (other than doing the standard Find which will also bring back every text match, including comments and markup). You can do a search on code specific usages with string.Empty.
  • MaxOvrdrv
    MaxOvrdrv over 9 years
    This is actually a good way of fixing the problem. The same thing can be used to carry/set other device dependent variables like Environment.Newline .. The only thing missing from your example would be a check on the variable for null, and throwing an exception back to the developer telling him that while it's nullable, it's not accepted. if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");} or something like that. But i really like this! Any other caveats to doing it your way?
  • Jon Skeet
    Jon Skeet over 9 years
    @MaxOvrdrv: You don't want it being null to be an error - the whole point is that when it's null, you compute a default. The caveat is that it doesn't allow null to be passed through as a valid value in itself.
  • MaxOvrdrv
    MaxOvrdrv over 9 years
    You are completely right about that. My bad. -- And yes, that would be the only real caveat wouldn't it... that's not too bad. Again: i really like this solution! :) Thanks for posting it! :)
  • Jim Balter
    Jim Balter almost 9 years
    There are also invisible identifier characters, so something that looks like String_Empty isn't necessarily. The Unicode standard has a largely ignored chapter on security considerations.
  • usefulBee
    usefulBee over 8 years
    string.Empty is useful to find out the exact intention of the programmer. "" does not tell anything about the intention, what if the programmer intention was to initialize the variable like this "lol" but forgot...in this case there are endless possibilities and string,Empty comes handy and does a better job
  • jbob77435
    jbob77435 almost 3 years
    But using 'string.Empty` reads so much nicer than "" string literal. Do others agree with string.Empty being better from a readability perspective?
  • Jon Skeet
    Jon Skeet almost 3 years
    @jbob77435: I absolutely disagree - I find "" to be far more readable.
  • jbob77435
    jbob77435 almost 3 years
    @JonSkeet Well, I suppose this issue is subjective. But as you taught me almost everything I know via your excellent book C# in Depth, I do find myself questioning my taste in this matter.