C# 4.0 - How to Handle Optional String Parameters
Asked Answered
R

7

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?

Revenant answered 31/8, 2010 at 5:41 Comment(5)
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)Redden
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? ](#508423). @Dave, there's no Unicode thing, here. "" is fine; see also [ In C#, should I use string.Empty or String.Empty or “” ? ](#263691).Murrhine
@prateeksaluja20 - what does the title/tags mention???Revenant
@STW - why did you remove my edit??Revenant
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.Aesculapian
A
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?

Aflutter answered 31/8, 2010 at 5:47 Comment(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 "".Revenant
Facetious mode: If you want people to read your code as 'zero' rather than 'nought' then maybe it's OKContainer
Why such a rude response? The OP had a legitimate question.Oxysalt
A
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);
}
Amen answered 23/9, 2010 at 7:34 Comment(5)
The default(string) value is null, not empty string.Spathose
@allonhadaya, specifying a non-null default value doesn’t prevent anyone from explicitly passing null :-p.Emilio
@binki, I'm not sure I understand your point. What do you mean?Spathose
@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 nullEmilio
@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'.Spathose
R
6

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
}
Raisaraise answered 29/9, 2016 at 20:36 Comment(0)
A
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!

Aesculapian answered 31/8, 2010 at 5:48 Comment(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 "".Revenant
V
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.

Volnak answered 31/8, 2010 at 6:7 Comment(0)
B
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;
}
Breakage answered 5/4, 2011 at 16:8 Comment(0)
A
-1
   private void Foo(string optionalString = emptyString)
    {
        if (string.IsNullOrEmpty(optionalString )) 
        { 
            return; 
        }
    }
Azurite answered 24/4 at 8:54 Comment(3)
Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. Would you kindly edit your answer to include additional details for the benefit of the community?Hasid
Also, why do you prefer this approach over those already given?Hasid
This looks like a duplication of g2gl2z's answer; with details and citation removed.Caryncaryo

© 2022 - 2024 — McMap. All rights reserved.