string.Empty vs null. Який з них ви використовуєте?


84

Нещодавно колега по роботі сказав мені не використовувати string.Emptyпри встановленні рядкової змінної, а використовувати, nullоскільки це забруднює стек?

Каже, не роби

string myString=string.Empty; але робіть string mystring=null;

Це насправді має значення? Я знаю, що рядок - це об’єкт, тому це начебто має сенс.

Я знаю, це безглузде запитання, але який ваш погляд?


1
Я не зовсім впевнений, чому б ви зробили це ... Ви можете навести трохи більше коду, який ви обговорювали, як приклад?
Стюсміт

немає коду. Я попросив свого колегу поглянути на щось, що я налагоджував, і він сказав, що за загальним правилом "не використовуй string.empty" встановіть його на нуль, коли він надходить у стек. Особисто я завжди використовував string.Empty оскільки час його виходу мав бути правильним для використання, а не "".
користувач712923


Я маю на увазі це ... string.Empty,, ""і nullвсі вони є постійними значеннями, але всі вони досить "прості", і я не можу зрозуміти, чому ви призначили одне змінній. Якщо вам потрібно захопити outзмінну, чому б просто не використовувати string myString;?
Stusmith

8
У наші дні аргументи щодо таких тем, які не зосереджені на читабельності та семантиці, а на абсурдних мікро-оптимізаціях, у кращому випадку є слабкими. Використовуйте те, що означає щось правильне для вашого даного контексту. (наприклад, якщо ви знаєте, що хтось не має по батькові, ви використовуєте String.Empty; якщо ви не знаєте, чи є у когось друге ім’я, яке ви використовуєте null). Потім, як тільки у вас з’явиться правильне значення, напишіть код таким чином, щоб він був чітко правильним і легко підтримувався.
jason

Відповіді:


110

nullі Emptyдуже різні, і я не пропоную довільно переключатися між ними. Але жоден із них не має жодних додаткових "витрат", оскільки Emptyє єдиним фіксованим посиланням (його можна використовувати будь-яку кількість разів).

У стеці немає "забруднення", спричиненого ldsfld - це занепокоєння .... божевільне. Завантаження a null, можливо, незначно дешевше, але може спричинити винятки з нульовими посиланнями, якщо ви не обережно перевіряєте значення.

Особисто я не використовую ні того, ні іншого ... Якщо я хочу порожній рядок, який я використовую ""- просто і очевидно. Стажування означає, що це також не має накладних витрат на використання.


На рівні IL різниця тут між "" та "Порожнім" просто ldstr проти ldsfld - але обидва дають однакові посилання на інтернований рядок. Крім того, в більш пізніх версіях .NET JIT має прямий перехоплення їх, даючи посилання на порожній рядок, не виконуючи фактичного пошуку статичного поля. В основному, точно немає підстав дбати в будь-якому випадку, крім читабельності. Я просто використовую "".


5
@ user712923, якщо він повернеться з якимись конкретними проблемами, я хотів би їх почути
Марк Гравелл

4
@Marc: "" ASAIK створює об'єкт, де string.Empty немає .. перевірити це і це . Це має щось спільне із пулом стажерів ....
Джалал Саїд,


1
+1 за використання ""замість шестикратно довшого типового коду. Хто б не пропагував цю нісенітницю ?! @Jalal Те, що публікація Бреда Абрамса серйозно застаріла, і якщо компілятор все одно не оптимізує ці два коди, щоб зробити те саме, тоді сором за Microsoft! Але не наша робота виправляти їх роботу. І насправді нам не потрібно: у другому посиланні Лассе (у коментарях) порівняв вихідні дані збірки порівняння з будь-яким із варіантів: вони ідентичні.
Конрад Рудольф

1
@Konrad: Одним з прикладів є те, що відбувається при об'єднанні постійних рядків: клас рядків використовує пул стажерів, тому, коли ви створюєте новий рядок, клас перевіряє, чи рядок вже є в пулі, а потім, якщо не додав його до пулу .. Через це, коли ""він буде здійснювати пошук у всьому пулі, щоб перевірити, чи є він уже там чи ні, і саме таким чином при використанні string.Empty;він буде використовувати це заздалегідь визначене значення, і пошук більше не буде існувати. клас також викрив ці методи: string.Intern/IsInternedперевірте це
Джалал Саїд

34

Це не "забруднює стек", немає технічної причини, але є велика різниця між встановленням змінної посилання на об'єкт (навіть якщо це порожній рядок) та null. Це не одне і те ж, і їх слід використовувати по-різному.

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

Редагувати, додано приклади:

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

  • Ви можете використовувати nullдля параметра конфігурації, який не вказаний у файлі конфігурації. У цьому випадку string.Emptyбуде використано, якщо параметр config був присутній, але бажаним налаштованим значенням був порожній рядок.


Я ніколи так не думав, мушу визнати. Беручи до уваги те, що ви щойно сказали, чи не заперечуєте ви, щоб навести мені приклад, я знаю, що ваше пояснення само собою пояснюється, але все ж ... спасибі
user712923

2
Ну, єдина причина вибрати той чи інший заснована на місці, де ви б його використали. Тобто використовувати, string.Emptyабо ""коли ви хочете використовувати порожній рядок і nullколи ви хочете вказати, що даних немає. Ви можете використовувати string.Emptyяк постфікс за замовчуванням для імені людини (наприклад, більшість людей не має доктора наук) - і nullдля параметра конфігурації, який не вказаний у файлі конфігурації. У цьому другому випадку string.Emptyбуде використано, якщо параметр config був присутній, але бажаним налаштованим значенням був порожній рядок.
Kieren Johnstone

@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} як масив байтів для збереження, і знову при завантаженні може бути інтерпретований назад до нуля.

Є більше переваг, таких як знання розміру, який слід завантажити або накопичити, якщо ви закріпите кілька рядків.

Повернемось до теми - це буде .. добре забруднити стек, оскільки ті самі принципи, що описані, використовуються будь-якою системою для диференціації нулів від порожніх .. так що так, рядок. назвіть це забрудненням .. це просто ще 1 байт.


1

На нього відповіли до смерті, але нуль означає відсутність значення, не ініціалізоване. 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. Не впевнений, чому це так, але ось ви йдете. Зараз я просто використовую ""скрізь для послідовності.


1
Так. Ось чому ми всі повинні мати звичку перевіряти .Length==0або використовувати.Compare()
zanlok

14
Це запитання стосується c # not js
Cole Johnson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.