Инициализация строки по умолчанию: NULL или Empty?

Я всегда инициализировал свои строки в NULL, думая, что NULL означает отсутствие значения, и значение "или String.Empty является допустимым значением. В последнее время я видел больше примеров кода, где String.Empty считается значением по умолчанию или не представляет значения. Это поражает меня как нечетное, с новыми добавленными типами с нулевым значением в С# кажется, что мы делаем шаги назад со строками, не используя NULL для представления" Нет значения".

Что вы используете в качестве инициализатора по умолчанию и почему?

Изменить: основываясь на ответах, я буду дальше мыслить

  • Избегайте обработки ошибок. Если значение не должно быть нулевым, зачем оно было установлено на NULL в первую очередь? Возможно, было бы лучше определить ошибку в том месте, где она происходит, а не покрывать ее остальной частью вашей кодовой базы?

  • Избегайте нулевых проверок Если вы устали от выполнения нулевых проверок в коде, не лучше ли абстрагировать нулевые проверки? Возможно, оберните (или продолжите!) Строковые методы, чтобы сделать их NULL безопасными? Что произойдет, если вы постоянно используете String.Empty, а нуль будет работать в вашей системе, начинаете ли вы добавлять NULL в любом случае?

Я не могу не вернуться к мнению, что это лень. Любой администратор базы данных пошлет вам девять способов глупости, если вы использовали '' вместо NULL в своей базе данных. Я думаю, что одни и те же принципы применяются в программировании, и кто-то должен удалять их вверх головой, которые используют String.Empty, а не NULL, чтобы не представлять значения.

Вопросы, относящиеся

Ответ 1

+1 для различения "пустой" и NULL. Я согласен, что "пустой" должен означать "действительный, но пустой" и "NULL" должен означать "недействительный".

Итак, я бы ответил на ваш вопрос следующим образом:

empty, когда я хочу действительное значение по умолчанию, которое может быть изменено или не изменено, например, среднее имя пользователя.

NULL, если это ошибка, если следующий код не задает значение явно.

Ответ 2

Согласно MSDN:

Инициализируя строки с Empty вместо null, вы можете уменьшить вероятность появления NullReferenceException.

Всегда использование IsNullOrEmpty() является хорошей практикой.

Ответ 3

Почему вы хотите, чтобы ваша строка была инициализирована вообще? Вам не нужно инициализировать переменную, когда вы объявляете ее, и IMO, вы должны делать это только тогда, когда назначенное вами значение является допустимым в контексте блока кода.

Я вижу это много:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else
{
  name = "bar";
}

return name;

Не инициализация нулевого значения будет столь же эффективной. Кроме того, чаще всего вы хотите присвоить значение. Путем инициализации до нуля вы можете пропустить коды кода, которые не присваивают значение. Например:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else if (othercondition)
{
  name = "bar";
}

return name; //returns null when condition and othercondition are false

Если вы не инициализируете значение null, компилятор будет генерировать ошибку, говоря, что не все пути кода присваивают значение. Конечно, это очень простой пример...

Маттийс

Ответ 4

Для большинства программ, которые на самом деле не являются программным обеспечением для обработки строк, логика программы не должна зависеть от содержимого строковых переменных. Всякий раз, когда я вижу что-то подобное в программе:

if (s == "value")

У меня плохое чувство. Почему в этом методе есть строковый литерал? Какая настройка s? Знает ли он, что логика зависит от значения строки? Знает ли он, что для работы должно быть более строгим? Должен ли я исправлять это, меняя его на использование String.Compare? Должен ли я создавать Enum и анализировать его?

С этой точки зрения, вы добираетесь до философии кода, которая довольно проста: вы избегаете изучения содержимого строки, где это возможно. Сравнение строки с String.Empty на самом деле является просто особым случаем сравнения его с литералом: это что-то, что нужно избегать, если вам действительно не нужно.

Зная это, я не моргаю, когда вижу что-то вроде этого в нашей базе кода:

string msg = Validate(item);
if (msg != null)
{
   DisplayErrorMessage(msg);
   return;
}

Я знаю, что Validate никогда не вернет String.Empty, потому что мы пишем лучший код, чем это.

Конечно, остальной мир не работает так. Когда ваша программа имеет дело с пользовательским вводом, базами данных, файлами и т.д., Вы должны учитывать другие философии. Там, это ваш код, чтобы наложить порядок на хаос. Часть этого порядка знает, когда пустая строка должна означать String.Empty и когда она должна означать null.

(Просто чтобы убедиться, что я не говорю из своей задницы, я просто искал нашу кодовую базу для `String.IsNullOrEmpty '. Все 54 ее появления относятся к методам, которые обрабатывают ввод пользователя, возвращают значения из скриптов Python, проверяют значения, полученные из внешних API и т.д.)

Ответ 5

Это зависит.

Вам нужно узнать, отсутствует ли значение (возможно ли, чтобы он не определялся)?

Является ли пустая строка допустимым значением для использования этой строки?

Если вы ответили "да" на оба, то вы захотите использовать null. В противном случае вы не можете определить разницу между "no value" и "empty string".

Если вам не нужно знать, нет ли значения, то пустая строка, вероятно, будет более безопасной, поскольку она позволяет пропустить нулевые проверки там, где вы ее используете.

Ответ 6

Это на самом деле зияющая дыра на языке С#. Невозможно определить строку, которая не может быть нулевой. Это приводит к таким простым проблемам, как тот, который вы описываете, что заставляет программистов принимать решение, которое им не нужно делать, поскольку во многих случаях NULL и String.Empty означают одно и то же. Это, в свою очередь, может привести к тому, что другим программистам придется обрабатывать как NULL, так и String.Empty, что раздражает.

Большая проблема заключается в том, что базы данных позволяют вам определять поля, которые сопоставляются с строкой С#, но поля базы данных могут быть определены как NOT NULL. Таким образом, нет способа точно представлять, скажем, поле varchar (100) NOT NULL в SQL Server с использованием типа С#.

Другие языки, такие как SpeС#, разрешают это.

На мой взгляд, неспособность С# определить строку, которая не допускает null, столь же плоха, как и предыдущая невозможность определить int, которая допускает null.

Чтобы полностью ответить на ваш вопрос: я всегда использую пустую строку для инициализации по умолчанию, потому что она больше похожа на то, как работают типы данных базы данных. (Edit: Это утверждение было очень неясным. Оно должно читать "Я использую пустую строку для инициализации по умолчанию, когда NULL является избыточным состоянием, так же, как я установил столбец базы данных как NOT NULL, если NULL будет избыточным состоянием., многие из моих столбцов БД настроены как NOT NULL, поэтому, когда я ввожу их в строку С#, строка будет пустой или имеет значение, но никогда не будет NULL. Другими словами, я только инициализирую строку в NULL если значение null имеет значение, отличное от значения String.Empty, и я считаю, что случай будет меньше обычного (но люди здесь дали законные примеры этого случая).)

Ответ 8

Я либо устанавливаю его на "", либо null - я всегда проверяю с помощью String.IsNullOrEmpty, так что все нормально.

Но внутреннее выродка во мне говорит, что я должен установить его значение null, прежде чем у меня будет подходящее значение для него...

Ответ 9

Я всегда объявляю строку с string.empty;

Ответ 10

Возможно ли, что это метод избегания ошибок (желательно или нет)? Поскольку "" все еще является строкой, вы могли бы вызывать на ней строковые функции, что привело бы к исключению, если оно было NULL?

Ответ 11

Я всегда инициализирую их как NULL.

Я всегда использую string.IsNullOrEmpty(someString), чтобы проверить его значение.

Simple.

Ответ 12

Это зависит от ситуации. В большинстве случаев я использую String.Empty, потому что я не хочу делать нулевые проверки каждый раз, когда я пытаюсь использовать строку. Это делает код намного проще, и вы с меньшей вероятностью вводите нежелательные ошибки NullReferenceException.

Я устанавливаю только строку, когда мне нужно знать, было ли оно установлено или нет, и где пустая строка является чем-то действительным для ее установки. На практике я нахожу эти ситуации редкими.

Ответ 13

Пустая строка - это значение (фрагмент текста, который, кстати, не содержит букв). Null означает значение no.

Я инициализирую переменные до нуля, когда хочу указать, что они не указывают или не содержат действительные значения - когда намерение не имеет значения.

Ответ 14

Повторяя ответ Tomalak, имейте в виду, что при назначении строковой переменной начальному значению null ваша переменная больше не является строковым объектом; то же самое с любым объектом в С#. Таким образом, если вы попытаетесь получить доступ к любым методам или свойствам для своей переменной и предположите, что это строковый объект, вы получите исключение NullReferenceException.

Ответ 15

Строки не являются типами значений и никогда не будут; -)

Ответ 16

Нуль должен использоваться только в случаях, когда значение является необязательным. Если значение не является необязательным (например, "Имя" или "Адрес" ), значение никогда не должно быть пустым. Это относится к базам данных, а также к POCOs и пользовательскому интерфейсу. Null означает, что "это значение является необязательным и в настоящее время отсутствует".

Если ваше поле не является необязательным, вы должны инициализировать его как пустую строку. Чтобы инициализировать его как null, ваш объект окажется в недопустимом состоянии (недействителен вашей собственной моделью данных).

Лично я предпочел бы, чтобы строки не были обнуляемыми по умолчанию, но вместо этого были только нулевыми, если мы объявляем "строку?". Хотя, возможно, это невозможно или логично на более глубоком уровне; не уверен.

Ответ 17

Я думаю, что нет причин не использовать null для неназначенного (или в этом месте в неточном потоке программы) значения. Если вы хотите отличить, то == null. Если вы просто хотите проверить определенное значение и не заботитесь о том, является ли оно нулевым или чем-то другим, String.Equals( "XXX", MyStringVar) просто отлично.