С# 4.0 - Как обрабатывать необязательные строковые параметры
Этот код недействителен:
private void Foo(string optionalString = string.Empty)
{
// do foo.
}
Но этот код:
private void Foo(string optionalString = "")
{
// do foo.
}
Почему? Поскольку string.Empty является полем readonly, а не константой, а значения по умолчанию для необязательных параметров должны быть константой времени компиляции.
Итак, на мой вопрос... (ну, беспокойство)
Это то, что я должен был сделать:
private const string emptyString = "";
private void Foo(string optionalString = emptyString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}
Как вы, парни, обрабатываете необязательные строковые параметры?
Почему они не могут String.Empty константу времени компиляции?
Ответы
Ответ 1
Ummm... что случилось со строкой optionalParm = "" еще раз? Почему это плохо? Вы действительно думаете, что вам нужна символическая константа для пустой строки в этом случае? Как насчет этого?
const int Zero = 0;
void SomeMethod(int optional = Zero) { }
Неужели это кажется вам глупым?
Ответ 2
если вам не нравится значение ", вы можете использовать значение по умолчанию (строка).
Я играл с ним, и это разрешено.
private static void foo(string param = default(string)) {
if (!string.IsNullOrEmpty(param)) // or param != default(string)
Console.WriteLine(param);
}
Ответ 3
Лучший способ справиться с ними - с помощью
private void Foo(string optionalString = "")
{
// do foo.
}
Поэтому вы не можете использовать String.Empty. Все признают "", но если бы я нашел optionalString = nullString
, я не был бы уверен, что думать. Если ничего другого, назовите вещь emptyString
- это не null!
Ответ 4
Предупреждение анализа кода 1026 говорит, что не использовать необязательные параметры. Лучше использовать методы перегрузки, например:
private void Foo()
{
Foo(string.Empty);
}
private void Foo(string optionalString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}
Ответ 5
Я отвечаю на этот вопрос.
Why can they not make String.Empty a compile-time constant?
Вот код дизассемблирования через Reflector of String.cs в mscorlib.dll
public static readonly Empty;
static String()
{
Empty = "";
WhitespaceChars = new char[] {
'\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', '', '\u2028', '\u2029', ' ', ''
};
}
Итак, в платформе windows string.Empty является именно "". Но знаете ли вы, что у марсианки есть другое определение для Empty и WhitespaceChars в их ОС.
Ответ 6
Если вы готовы проиграть и обработать нулевые символы "", а пробельные символы будут одинаковыми, вы можете по умолчанию null
. Это очень удобно, когда имя пользователя и пароль являются необязательными полями из-за возможности надежного подключения к db. Вы можете изменить эту логику на строки reset на null
и, таким образом, изменить assert и if
. Важная часть имеет согласованное соглашение.
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;
}