RPM1984
RPM1984

Reputation: 73123

C# 4.0 - How to Handle Optional String Parameters

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?

Upvotes: 20

Views: 67455

Answers (7)

Vivek Kr
Vivek Kr

Reputation: 1

   private void Foo(string optionalString = emptyString)
    {
        if (string.IsNullOrEmpty(optionalString )) 
        { 
            return; 
        }
    }

Upvotes: -1

g2gl2z
g2gl2z

Reputation: 61

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
}

Upvotes: 6

Hamish Grubijan
Hamish Grubijan

Reputation: 10830

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;
}

Upvotes: 0

Danil
Danil

Reputation: 1893

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);
}

Upvotes: 8

Ed Swangren
Ed Swangren

Reputation: 124770

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?

Upvotes: 15

Cheng Chen
Cheng Chen

Reputation: 43531

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.

Upvotes: 1

STW
STW

Reputation: 46394

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!

Upvotes: 2

Related Questions