20

This code is not valid:

private void Foo(string optionalString = string.Empty)
{
   // do foo.
}

But this code is:

private void Foo(string optionalString = "")
{
   // do foo.
}

Why? Because string.Empty is a readonly field, not a constant, and defaults for optional parameters must be a compile-time constant.

So, onto my question... (well, concern)

This is what i've had to do:

private const string emptyString = "";

private void Foo(string optionalString = emptyString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}

How do you guys handle optional string parameters?

Why can they not make String.Empty a compile-time constant?

STW
  • 44,917
  • 17
  • 105
  • 161
RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • 2
    why not stick with ""? That's all I ever do, but that's also because I don't understand the advantage of using String.Empty. Must be a unicode thing, but I don't ever have to worry about that (at least not yet... yikes) – Dave Aug 31 '10 at 05:45
  • 1
    I am confused why you think you *need* to do this. I consider `nullString` a confusing name, because at first glance I would be inclined to think it was `null`, not `""`. As for your final question, see [ Why isn't String.Empty a constant? ](http://stackoverflow.com/questions/507923/why-isnt-string-empty-a-constant). @Dave, there's no Unicode thing, here. `""` is fine; see also [ 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). – Matthew Flaschen Aug 31 '10 at 05:48
  • @prateeksaluja20 - what does the title/tags mention??? – RPM1984 Aug 31 '10 at 06:51
  • @STW - why did you remove my edit?? – RPM1984 Sep 01 '10 at 00:00
  • It didn't add to the question--and the answer's weren't attacking you, they may have been blunt, but your original question wasn't exactly neutral. – STW Sep 01 '10 at 02:21

6 Answers6

15

Ummm... what's wrong with string optionalParm = "" again? Why is that bad? Do you really think you need a symbolic constant for an empty string in this case? How about this then?

const int Zero = 0;

void SomeMethod(int optional = Zero) { }

Does that seem at all silly to you?

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 3
    Agreed, i named that badly. I just got so used to using string.empty for most string operations, that when i started using Optional Params, i didnt like the fact i had to go back to "". Guess ill stick with "". – RPM1984 Aug 31 '10 at 06:03
  • Facetious mode: If you want people to read your code as 'zero' rather than 'nought' then maybe it's OK – Davos Mar 31 '15 at 03:52
  • 15
    Why such a rude response? The OP had a legitimate question. – webworm Jan 28 '16 at 16:26
8

if you don't like "" value you can use default(string).
I played with it and it is allowed.

private static void foo(string param = default(string)) {
    if (!string.IsNullOrEmpty(param)) // or param != default(string)
        Console.WriteLine(param);
}
Danil
  • 1,883
  • 1
  • 21
  • 22
  • 6
    The default(string) value is null, not empty string. – allonhadaya Jul 05 '12 at 15:17
  • @allonhadaya, specifying a non-`null` default value doesn’t prevent anyone from explicitly passing `null` :-p. – binki May 20 '14 at 13:00
  • @binki, I'm not sure I understand your point. What do you mean? – allonhadaya May 22 '14 at 17:12
  • @allonhadaya, I forget. Maybe I was trying to say that the default of `null` makes more sense than specifying a parameter default of `""`. In some cases you do want to distinguish between the empty string and `null` and having a default value of `null` implies that your method handles an explicitly-specified `null` value nicely. Though this has more to do with the OP’s choice to use `""` instead of `null`… – binki May 27 '14 at 15:34
  • @binki, Aha - Functions get messy when the choice of default value is a member of the expected domain; it can then no longer be used as a reliable signal. `null` tends to be a better signal than `""` because it is the only member of the `string` type which implies 'no value'. – allonhadaya May 27 '14 at 16:46
5

Code Analysis warning 1026 says not to use optional parameters. It's better style to use overload methods, like this:

private void Foo()
{
   Foo(string.Empty);
}
private void Foo(string optionalString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}
g2gl2z
  • 51
  • 1
  • 3
2

The best way to handle them is with:

private void Foo(string optionalString = "")
{
   // do foo.
}

So you can't use String.Empty. Everyone recognizes "", but if I found optionalString = nullString I wouldn't be sure what to think. If nothing else, name the thing emptyString--it's not null!

STW
  • 44,917
  • 17
  • 105
  • 161
  • 1
    Agreed, i named that badly. I just got so used to using string.empty for most string operations, that when i started using Optional Params, i didnt like the fact i had to go back to "". Guess ill stick with "". – RPM1984 Aug 31 '10 at 06:01
1

I'm answering this question.

Why can they not make String.Empty a compile-time constant?

Here is the disassemble code via Reflector of String.cs in mscorlib.dll

public static readonly Empty;
static String()
{
    Empty = "";
    WhitespaceChars = new char[] { 
        '\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
        ' ', ' ', ' ', ' ', '​', '\u2028', '\u2029', ' ', ''
     };
}

So in windows platform, string.Empty is exactly "". But do you know, Martian have a different definition for Empty and WhitespaceChars in their OS.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
0

If you are willing to play lose and treat null, "", and whitespace characters to be the same, then you can default to null. This becomes very handy when user name and password are optional fields due to a possibility of trusted connection to a db. You could change this logic to reset strings to null and thus modify the assert and the if. The important part is having a consistent convention.

private void RunSql(string serverName, string databaseName, string userName = null, string password = null)
{
    userName = Strip(userName);
    password = Strip(password);

    // The `MsTest` assert - works in both `Debug` and `Release` modes.
    Assert.AreEqual<bool>(
        userName == String.Empty,
        password == String.Empty,
        "User name and password should be either both empty or both non-empty!");
   Assert.IsFalse(String.IsNullOrWhiteSpace(serverName));
   Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName));

   var cmdBuilder = new StringBuilder();
   cmdBuilder.AppendFormat("sqlcmd -E -S {0} -d {1} ", serverName, databaseName);
   if (userName.Length > 0)
   {
       cmdBuilder.AppendFormat("-U {0} -P {1} ", userName, password);
   }

   // Complete the command string.
   // Run the executable.
}

// Cannot think of a good name. Emptify? MakeNullIfEmpty?
private string Strip(string source)
{
    if (String.IsNullOrWhiteSpace(source))
    {
        return String.Empty;
    }

    return source;
}
Hamish Grubijan
  • 10,562
  • 23
  • 99
  • 147