string.Empty vs null.Какой из них вы используете?

85

Недавно коллега по работе сказал мне не использовать string.Emptyпри установке строковой переменной, а использовать, nullпоскольку она загрязняет стек?

Он говорит, не делай

string myString=string.Empty; но делать string mystring=null;

Это действительно важно? Я знаю, что строка - это объект, поэтому в этом есть смысл.

Я знаю, это глупый вопрос, но каково ваше мнение?

user712923
источник
1
Я не совсем уверен, почему вы это сделали ... не могли бы вы привести немного больше кода, который вы обсуждали, в качестве примера?
stusmith
кода нет. Я попросил своего коллегу взглянуть на то, что я отлаживал, и он сказал, что в качестве общего правила «не используйте string.empty» установите для него значение null, поскольку оно попадает в стек. Лично я всегда использовал string.Empty поскольку когда он вышел, предполагалось, что его лучше использовать, а не "".
user712923
Я имею в виду, что ... string.Empty, ""и null- все постоянные значения, но все они достаточно "простые", поэтому я не понимаю, почему вы назначаете одно значение переменной. Если вам нужно захватить outпеременную, почему бы просто не использовать string myString;?
stusmith
8
В наши дни аргументы по таким темам, которые не сосредоточены на удобочитаемости и семантике и сосредоточены на абсурдных микрооптимизациях, в лучшем случае слабы. Используйте то, что правильно для вашего контекста. (например, если вы знаете, что у кого-то нет второго имени, вы его используете String.Empty; если вы не знаете, есть ли у кого-то второе имя, которое вы используете null). Затем, когда у вас будет правильное значение, напишите код таким образом, чтобы он был четко правильным и легко поддерживаемым.
jason

Ответы:

111

nullи Emptyочень разные, и я не предлагаю произвольно переключаться между ними. Но ни то, ни другое не имеет дополнительной «стоимости», поскольку Emptyэто единственная фиксированная ссылка (вы можете использовать ее любое количество раз).

В стеке нет «загрязнения», вызванного ldsfld - это ... безумное беспокойство. Загрузка, nullвозможно, немного дешевле, но может вызвать исключения с нулевой ссылкой, если вы не будете осторожны при проверке значения.

Лично я не использую ни то, ни другое ... Если мне нужна пустая строка, я использую ""- просто и очевидно. Интернирование означает, что это также не имеет накладных расходов на использование.


На уровне IL разница между "" и Empty здесь просто ldstr vs ldsfld, но оба дают одну и ту же ссылку на одну интернированную строку. Более того, в более поздних версиях .NET JIT имеет прямой перехват их, давая ссылку на пустую строку без фактического поиска в статическом поле. По сути, в любом случае нет причин для беспокойства, кроме удобочитаемости. Я просто использую "".

Марк Гравелл
источник
5
@ user712923, если он вернется с какими-либо конкретными проблемами, я хотел бы их услышать
Марк Грейвелл
4
@Marc: ASAIK "" создает объект, в котором string.Empty не является ... проверьте то и это . Это как-то связано со струнным пулом стажеров ....
Сказал Джалал
7
@Hemal: String.IsNullOrEmpty ()
Винко Врсалович
1
+1 за использование ""вместо стандартного кода в шесть раз длиннее. Кто пропагандировал эту чушь ?! @Jalal Эта публикация Брэда Абрамса серьезно устарела, и если компилятор все еще не оптимизирует эти два кода, чтобы сделать то же самое, то позор Microsoft! Но исправлять их работу - не наша работа. И на самом деле нам это не нужно: во второй ссылке Лассе (в комментариях) сравнил результаты сборки сравнения с любым вариантом: они идентичны.
Конрад Рудольф
1
@Konrad: Одним из примеров является то, что происходит при объединении константных строк: строковый класс использует внутренний пул, поэтому, когда вы создаете новую строку, класс проверяет, находится ли строка уже в пуле, а затем, если она не добавлена, в пул .. Из-за этого, когда ""он будет искать весь пул, чтобы проверить, есть ли он там или нет, и именно так при использовании string.Empty;он будет использовать это предопределенное значение, и поиск больше не будет. класс также предоставил эти методы: string.Intern/IsInternedпроверьте это
Джалал Саид
35

Это не «загрязняет стек», нет никаких технических причин, но есть большая разница между установкой переменной для ссылки на объект (даже если это пустая строка) и null. Это не одно и то же, и их следует использовать по-разному.

nullследует использовать для обозначения отсутствия данных, string.Empty(или "") для обозначения наличия данных, фактически некоторого пустого текста. Есть ли конкретный случай, когда вы не уверены, что является наиболее подходящим?

Отредактировал, добавил примеры:

  • Вы можете использовать string.Emptyпостфикс по умолчанию для имени человека (например, у большинства людей нет докторской степени)

  • Вы можете использовать nullдля параметра конфигурации, который не был указан в файле конфигурации. В этом случае string.Emptyбудет использоваться, если параметр конфигурации присутствует, но желаемое настроенное значение представляет собой пустую строку.

Кирен Джонстон
источник
Должен признаться, я никогда так не думал. Учитывая то, что вы только что сказали, не могли бы вы привести мне пример. Я знаю, что ваше объяснение говорит само за себя, но все же ... спасибо
user712923
2
Что ж, единственная причина выбрать тот или иной зависит от того, где вы его используете. Т.е. используйте string.Emptyили, ""когда вы хотите использовать пустую строку и nullкогда вы хотите указать, что данных нет. Вы можете использовать string.Emptyпостфикс по умолчанию для имени человека (например, у большинства людей нет докторской степени) и nullдля параметра конфигурации, который не был указан в файле конфигурации. Во втором случае string.Emptyбудет использоваться, если параметр конфигурации присутствует, но желаемое настроенное значение представляет собой пустую строку.
Кирен Джонстон
@Kieren Johnstone, если у кого-то нет имени постфикса, почему бы не использовать его nullдля обозначения «без постфикса»?
OfirD
8

Они разные, поскольку другие уже ответили.

static void Main(string[] args)
{
    string s1 = null;
    string s2 = string.Empty;
    string s3 = "";
    Console.WriteLine(s1 == s2);
    Console.WriteLine(s1 == s3);
    Console.WriteLine(s2 == s3);
}

 results:
 false     - since null is different from string.empty
 false     - since null is different from ""
 true      - since "" is same as string.empty

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

Для сохранения строк в файл или сообщений:
вы, вероятно, захотите преобразовать строку в байты.
я рекомендую добавить 2 сегмента байтов заголовка к преобразованной строке.

сегмент 1 - метаинформация, которая хранится в 1 байте и описывает длину следующего сегмента.

сегмент 2 - содержит длину сохраняемой строки.

пример:
строка "abcd" - для упрощения я конвертирую ее с помощью кодировщика ASCII и получу {65,66,67,68}.
Вычислить сегмент 2 даст 4 - поэтому 4 байта - это длина преобразованной строки.
вычислить сегмент 1 даст 1 - поскольку для хранения информации о длине преобразованной строковой информации использовался только 1 байт (который был 4, т.е. если бы это было 260, я бы получил 2)

Новая полоса байтов теперь будет {1,4,65,66,67,68}, которую можно сохранить в файл.

Преимущество по отношению к предмету состоит в том, что если бы у меня была пустая строка для сохранения, я бы получил от преобразования пустой массив байтов длиной 0, а после вычисления сегментов у меня будет {1,0}, которое может быть сохраняется, а затем загружается и интерпретируется обратно в пустую строку. С другой стороны, если бы у меня было нулевое значение в моей строке, я бы в конечном итоге имел только {0} в качестве массива байтов для сохранения и снова при загрузке мог быть интерпретирован обратно в нулевое значение.

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

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

GY
источник
1

На него ответили до смерти, но null означает отсутствие значения, не инициализированный. string.Empty означает "" (пустая строка), как указано в MSDN.

Самый безопасный способ проверить наличие пустой или нулевой строки - использовать string.IsNullOrEmpty.

Карлос А Мериге
источник
-2

FWIW, я обнаружил , что смешивание ""и String.Emptyне работает:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"

var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

В частности, если вы используете $.trimдля получения значения пустого поля ввода DOM, а затем сравните его String.Empty, вы получите false. Не уверен, почему это так, но поехали. Я сейчас просто использую ""везде для единообразия.

user1072817
источник
1
Да. Вот почему мы все должны иметь привычку проверять .Length==0или использовать.Compare()
занлок
14
Этот вопрос касается C #, а не js
Коул Джонсон