У C # я хочу ініціалізувати значення рядка з порожнім рядком.
Як мені це зробити? Який правильний шлях, і чому?
string willi = string.Empty;
або
string willi = String.Empty;
або
string willi = "";
або що?
У C # я хочу ініціалізувати значення рядка з порожнім рядком.
Як мені це зробити? Який правильний шлях, і чому?
string willi = string.Empty;
або
string willi = String.Empty;
або
string willi = "";
або що?
Відповіді:
Використовуйте все, що ви та ваша команда вважаєте найбільш читабельним.
Інші відповіді підказують, що кожен рядок створюється новий рядок ""
. Це неправда - через строкове інтернування він буде створений або один раз за збірку, або один раз за AppDomain (або, можливо, один раз за весь процес - не впевнений на цьому фронті). Ця різниця незначна - масово, масово незначна.
Однак те, що вам здається більш зрозумілим - це інша справа. Це суб'єктивно і змінюватиметься від людини до людини - тому я пропоную вам дізнатися, що подобається більшості людей у вашій команді, і всі йти з цим для послідовності. Особисто мені ""
легше читати.
Аргумент, який ""
і " "
легко помиляється один з одним, насправді не змиває зі мною. Якщо ви не використовуєте пропорційний шрифт (а я не працював з будь-якими розробниками, які це роблять), визначити різницю досить просто.
string.Empty
не є постійною величиною . Це означає, що в ряді випадків, коли потрібна константа часу компіляції, string.Empty
навіть не є законною. Сюди входять case ""
блоки в switch
операторах, значення за замовчуванням необов'язкових параметрів , параметри та властивості при застосуванні атрибутів та безліч інших ситуацій (залишено читачеві). Отже, враховуючи, що string.Empty
це заборонено в деяких поширених ситуаціях, краще використовувати ""
конвенцію -верху.
Дійсно немає різниці з точки зору продуктивності та згенерованого кодом. Під час тестування працездатності вони рухалися вперед і назад, між якими один був швидшим проти іншого, і лише на мілісекунди.
Дивлячись на код за кадром, ви також не бачите різниці. Єдина відмінність полягає в ІЛ, які string.Empty
використовують опкод ldsfld
і ""
використовують опкод ldstr
, але це лише тому, що string.Empty
є статичним, і обидві інструкції роблять те саме. Якщо ви подивитеся на збірку, яка виробляється, вона точно така ж.
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
.method private hidebysig instance void
Test1() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] string test1,
[1] string test11)
IL_0000: nop
IL_0001: ldsfld string [mscorlib]System.String::Empty
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ret
} // end of method Form1::Test1
.method private hidebysig instance void
Test2() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] string test2,
[1] string test22)
IL_0000: nop
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ret
} // end of method Form1::Test2
string test1 = string.Empty;
0000003a mov eax,dword ptr ds:[022A102Ch]
0000003f mov dword ptr [ebp-40h],eax
string test11 = test1;
00000042 mov eax,dword ptr [ebp-40h]
00000045 mov dword ptr [ebp-44h],eax
string test2 = "";
0000003a mov eax,dword ptr ds:[022A202Ch]
00000040 mov dword ptr [ebp-40h],eax
string test22 = test2;
00000043 mov eax,dword ptr [ebp-40h]
00000046 mov dword ptr [ebp-44h],eax
Найкращий код - це зовсім не код :
Фундаментальний характер кодування полягає в тому, що наше завдання, як програмістів, - визнати, що кожне рішення, яке ми приймаємо, є компромісним. […] Почніть з стислості. Збільште інші розміри відповідно до тестування.
Отже, менше коду краще код: Воліють ""
в string.Empty
або String.Empty
. Ці два в шість разів більше, але без додаткової вигоди - звичайно, без додаткової ясності, оскільки вони виражають ту саму інформацію.
i
це краще , ніж довге ім'я змінного. Навіть загальніші, кращі імена змінних, які передають ту саму інформацію , з однаковою чіткістю, завжди бажані. Просто для того, щоб висловити необхідну інформацію, вам потрібна певна довжина символів, і я цього не заперечую (ніхто не є).
Одна відмінність полягає в тому, що якщо ви використовуєте switch-case
синтаксис, ви не можете писати, case string.Empty:
оскільки це не константа. Ви отримуєтеCompilation error : A constant value is expected
Перегляньте це посилання для отримання додаткової інформації: рядки-порожні-проти-порожні-котирування
switch
Затвердження один дуже хороший приклад. Крім того, якщо ви робите необов'язковий параметр, наприклад void MyMethod(string optional = "") { ... }
, його також неможливо використовувати string.Empty
. І тоді, звичайно, якщо ви хочете визначити const
поле або локальну змінну, const string myString = "";
знову ""
це єдиний варіант. Якби тільки string.Empty
було постійне поле, різниці не було б. Але це не так, тому в деяких випадках доводиться користуватися ""
. То чому б не використовувати ""
весь час?
string.Empty
перешкоджає досягти послідовності в кодовій базі: ви повинні використовувати дві різні сутності, щоб виразити одне і те ж. І щоб додати до списку речей, які ви не можете зробити: ви не можете використовувати string.Empty
з атрибутами .
Я волів би , string
щоб String
. вибираючи string.Empty
більш ""
є питанням вибору одного і приклеїти з ним. Перевагою використання string.Empty
є те, що це дуже очевидно, що ви маєте на увазі, і ви випадково не копіюєте на символи, що не друкуються, як "\x003"
у вашому ""
.
""
Я стверджую, що аргумент, який є небезпечним, коли копіювання / вставлення недійсне, тому що ви ніколи не копіюєте / вставляєте порожній рядок. Щодо інших рядків, звичайно, завжди слід пам’ятати про щось.
Я не збирався звучати, але я бачу, що тут викидається якась неправильна інформація.
Я, особисто, віддаю перевагу string.Empty
. Це особиста перевага, і я схиляюся до волі будь-якої команди, з якою працюю в кожному конкретному випадку.
Як згадували деякі інші, різниці між string.Empty
і між ними взагалі немає String.Empty
.
Крім того, і це маловідомий факт, використання "" цілком прийнятно. Кожен екземпляр "" "в інших середовищах створюватиме об'єкт. Однак .NET інтернує його рядки, тому майбутні екземпляри витягуватимуть ту саму незмінну рядок із пулу інтернів, і будь-яке звернення до продуктивності буде незначним. Джерело: Бред Абрамс .
String.Empty
і string.Empty
є рівнозначними. String
- ім'я класу BCL; string
це його псевдонім C # (або ярлик, якщо ви хочете). Те саме, що Int32
і з int
. Докладні приклади див. У документах .
Що ""
стосується, я не дуже впевнений.
Особисто я завжди користуюся string.Empty
.
Практично кожен розробник там знатиме, що означає "". Я особисто зіткнувся з String.Порожні вперше, і мені довелося витратити деякий час на пошук Google, щоб з'ясувати, чи справді вони - це те саме.
string.Empty
? Чи знаєте ви, що ви ""
вперше побачили це?
Ця тема досить стара і довга, тому вибачте мене, якщо про таку поведінку згадували десь ще. (І вкажіть мені на відповідь, яка охоплює це)
Я знайшов різницю в поведінці компілятора, якщо ви використовуєте string.Empty
або подвійні лапки. Різниця проявляється, якщо ви не використовуєте змінну рядка, ініціалізовану рядком.Порожня або з подвійними лапки.
У разі ініціалізації з string.Empty
цим попередженням компілятора
CS0219 - The variable 'x' is assigned but its value is never used
ніколи не випромінюється, тоді як у випадку ініціалізації з подвійними лапками ви отримуєте очікуване повідомлення.
Така поведінка пояснюється у статті Connect за цим посиланням: https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value
В основному, якщо я правильно розумію, вони хочуть дозволити програмісту встановити змінну зі значенням повернення функції для цілей налагодження, не турбуючи його попереджувальним повідомленням, і таким чином вони обмежили попередження лише у випадку призначення костантів та рядка. Порожня - це не константа, а поле.
var unused = "literal";
компілятор може повністю оптимізувати (видалити) декларацію . Він не може мати побічних ефектів. З іншого боку, var unused = MyClass.Member;
його не можна видалити повністю. Це тому, що читання Member
може мати побічні ефекти. Якщо Member
є статична властивість з get
аксесуаром, зрозуміло, що дзвінок до геттера повинен зберігатися. Але навіть якщо Member
це статичне поле, може виникнути побічний ефект, який може працювати статичний конструктор. Звичайно, було б погано мати стиль кодування . Але вам потрібна пустушка для читання Member
.
Я провів цей дуже простий тест, використовуючи наступний метод у консольній програмі:
private static void CompareStringConstants()
{
string str1 = "";
string str2 = string.Empty;
string str3 = String.Empty;
Console.WriteLine(object.ReferenceEquals(str1, str2)); //prints True
Console.WriteLine(object.ReferenceEquals(str2, str3)); //prints True
}
Це чітко говорить про те, що всі три змінні, а саме str1
, str2
і str3
хоча вони ініціалізовані за допомогою різного синтаксису, вказують на абсолютно той самий рядковий (нульової довжини) об’єкт у пам'яті. Я провів цей тест у консольній програмі .NET 4.5. Отже, всередині них немає різниці, і все це зводиться до зручності, яку ви хочете використовувати як програміст. Така поведінка рядкового класу відома як строкове інтернування в .NET. Ерік Ліпперта має дуже хороший блог тут , описує цю концепцію.
Я дуже віддаю перевагу String.Empty, окрім інших причин, щоб переконатися, що ви знаєте, що це таке, і що ви випадково не видалили вміст, а насамперед для інтернаціоналізації. Якщо я бачу рядок у лапках, мені завжди доводиться задаватися питанням, чи це новий код, і чи слід його вносити до рядкової таблиці. Тому щоразу, коли код змінюється / переглядається, вам потрібно шукати "щось у лапках", і так, ви можете відфільтрувати порожні рядки, але я кажу людям, що це добра практика ніколи не ставити рядки в лапки, якщо ви не знаєте, що це не буде локалізовано. .
Ніхто не згадував, що у VisualStudio String кольорово кодується інакше, ніж рядок. Що важливо для читабельності. Крім того, нижній регістр зазвичай використовується для vars і type, не велика справа, але String.Empty - це константа, а не var або type.
string
є синонімом до System.String
типу, Вони однакові.
Значення також ідентичні: string.Empty == String.Empty == ""
Я б не використовував "" константи символів у коді, швидше, string.Empty
або String.Empty
- простіше зрозуміти, що означає програміст.
Між, string
і String
мені подобається нижній регістр string
більше лише тому, що я працював з Delphi протягом багатьох років, і стиль Delphi - це малі літери string
.
Отже, якби я був вашим начальником, ви б писали string.Empty
Я вважала за краще б string.Empty
більш String.Empty
тому , що ви можете використовувати його без необхідності включати using System;
в файл.
Що стосується вибору ""
більш string.Empty
, це особисті переваги і має бути прийнято вашою командою.
string.Empty
константу без імпорту using System
простору імен - Ключові слова в C # просто перетворяться на їх цілком кваліфіковане ім'я, яке включає простір імен, а також перед тим, як записати як MSIL у висновку * .dll або *. файл EXE. Настільки ефективно string.Empty
виписується System.String.Empty
компілятором як у MSIL. І як ви вже можете знати, що якщо ви згадуєте повноцінне ім’я типу, то ви можете пропустити імпорт просторів імен у верхній частині файла коду.
Я не маю значення. Останній - це найшвидший набір :)
Не має значення - вони точно те саме. Однак головне, щоб ви були послідовними
ps Я весь час боюся з таким "правильним".
Це абсолютно перевагу в кодовому стилі, виконайте, як .NET обробляє рядки. Однак ось мої думки :)
Я завжди використовую імена типу BCL під час доступу до статичних методів, властивостей та полів: String.Empty
або Int32.TryParse(...)
абоDouble.Epsilon
Я завжди використовую ключові слова C # при оголошенні нових екземплярів: int i = 0;
абоstring foo = "bar";
Я рідко використовую недекларовані рядкові літерали, оскільки мені подобається мати можливість сканувати код, щоб поєднати їх у багаторазові названі константи. Компілятор так чи інакше замінює константи літералами, тому це скоріше спосіб уникнути магічних рядків / чисел і надати їм більше значення для імені. Плюс змінювати значення простіше.
Будь-яке з перших двох було б для мене прийнятним. Я б уникнув останнього, оскільки ввести помилку порівняно легко, поставивши пробіл між цитатами. Цього конкретного клопа було б важко знайти за допомогою спостереження. Якщо не було помилок друку, всі семантично рівнозначні.
[EDIT]
Крім того, ви можете завжди використовувати string
або String
консистенцію, але це тільки я.
Я особисто був свідком "", що спричиняв (незначні) проблеми двічі. Один раз був пов’язаний з помилкою молодшого розробника, нового в командному програмуванні, а інший був простим друком, але факт використання string.Empty дозволив би уникнути обох питань.
Так, це дуже важливий вирок, але коли мова дає вам кілька способів зробити, я схильний схилятися до того, який має найбільший нагляд за компілятором та найсильніший час виконання компіляції. Це не "". Вся справа в вираженні конкретних намірів.
Якщо ви введете string.EMpty або Strng.Empty, компілятор дає вам знати, що ви зробили це неправильно. Відразу. Він просто не складеться. Як розробник ви посилаєтесь на певні наміри, які компілятор (або інший розробник) жодним чином не може витлумачити неправильно, і коли ви зробите це неправильно, ви не можете створити помилку.
Якщо ви набираєте "", коли маєте на увазі "" або навпаки, компілятор із задоволенням робить те, що ви йому сказали. Інший розробник може або не може виявити ваш конкретний намір. Помилка створена.
Задовго до string.Empty була річ, я використовував стандартну бібліотеку, яка визначала константу EMPTY_STRING. Ми все ще використовуємо цю константу в операторах випадків, коли string.Empty не дозволено.
Коли це можливо, покладіть компілятор на роботу для вас і усуньте можливість помилок людини, незалежно від того, наскільки мало. IMO, це козир "читабельності", як цитували інші.
Специфіка та складання часу виконання. Це що на вечерю.
Компілятор повинен з часом зробити їх однаковими. Виберіть стандарт, щоб ваш код було легко читати, і дотримуйтесь його.
Я просто дивився на якийсь код, і це запитання вискакувало мені на думку, яке я читав деякий час раніше. Це, безумовно, питання читабельності.
Розглянемо наступний код C # ...
(customer == null) ? "" : customer.Name
проти
(customer == null) ? string.empty : customer.Name
Я особисто вважаю останнє менш неоднозначним і легшим для читання.
Як зазначають інші, фактичні відмінності незначні.
Хоча різниця дуже, ДУЖЕ мало, різниця все ще існує.
1) "" створює об'єкт, коли String.Empty не робить. Але цей об'єкт буде створений один раз і буде посилатися з пулу рядків пізніше, якщо у вас є інший "" код.
2) Рядок і рядок однакові, але я б рекомендував використовувати String.Empty (як і String.Format, String.Copy тощо), оскільки позначення крапок вказують на клас, а не на оператор, а клас, що починається з великої літери, відповідає Стандарти кодування C #.
На http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx :
Як випливає з Девіда, різниці між ними є
String.Empty
і""
досить малі, але є різниця.""
насправді створюється об’єкт, він, ймовірно, буде витягнутий з пулу інтернів, але все ж ... покиString.Empty
створює жоден об'єкт ... тому, якщо ви справді шукаєте в кінцевому рахунку ефективність пам'яті, я пропонуюString.Empty
. Однак ви повинні пам’ятати, що різниця настільки дрібницька, що вам сподобається ніколи не бачити її у своєму коді…
ЩодоSystem.String.Empty
абоstring.Empty
абоString.Empty
… мій рівень догляду низький ;-)
Порожня рядок - це як порожній набір просто ім'я, яке всі використовують для виклику ""
. Також у формальних мовах рядки, створені з алфавіту, які мають нульову довжину, називаються порожнім рядком. І набір, і рядок мають спеціальний символ для цього. Порожній рядок: ε та порожній набір: ∅. Якщо ви хочете поговорити про цей рядок нульової довжини, ви назвете його порожнім рядком, щоб усі точно знали, про що ви маєте на увазі. Тепер, якщо ви назвали його порожнім рядком, чому б не використовувати його string.Empty
в коді, його показник має намір явний. Недоліком є те, що він не є постійним і тому недоступний скрізь, як в атрибутах. (З технічних причин це не є постійною, див. Довідкове джерело.)
Я віддаю перевагу ""
тому, що він коротший і String.Empty
вирішує проблему, якої не існує.