Reputation: 73123
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
Reputation: 1
private void Foo(string optionalString = emptyString)
{
if (string.IsNullOrEmpty(optionalString ))
{
return;
}
}
Upvotes: -1
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
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
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
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
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
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