В C # я хочу инициализировать строковое значение пустой строкой.
Как мне это сделать? Каков правильный путь и почему?
string willi = string.Empty;
или
string willi = String.Empty;
или
string willi = "";
или что?
В C # я хочу инициализировать строковое значение пустой строкой.
Как мне это сделать? Каков правильный путь и почему?
string willi = string.Empty;
или
string willi = String.Empty;
или
string willi = "";
или что?
Ответы:
Используйте то, что вы и ваша команда считаете наиболее читабельным.
Другие ответы предполагают, что новая строка создается каждый раз, когда вы используете ""
. Это не так - из-за интернирования строк он будет создаваться либо один раз для сборки, либо один раз для домена приложения (или, возможно, один раз для всего процесса - не уверен на этом фронте). Эта разница незначительна - в широком масштабе, массово незначительна.
Однако то, что вы находите более читабельным, - это другое дело. Это субъективно и будет варьироваться от человека к человеку - поэтому я предлагаю вам узнать, что нравится большинству людей в вашей команде, и все согласны с этим. Лично мне ""
легче читать.
Аргумент, что ""
и " "
их легко принять друг за друга, на самом деле меня не касается. Если вы не используете пропорциональный шрифт (а я не работал ни с одним из разработчиков), довольно легко заметить разницу.
string.Empty
не является константой . Это означает, что в ряде случаев, когда требуется постоянная времени компиляции, string.Empty
это даже не допустимо. Это включает case ""
в себя блоки в switch
операторах, значения по умолчанию необязательных параметров , параметры и свойства в применении атрибутов , а также множество других ситуаций (оставленных читателю). Поэтому, учитывая, что string.Empty
это запрещено в некоторых общих ситуациях, лучше использовать ""
соглашение везде.
Там действительно нет никакой разницы с точки зрения производительности и кода. При тестировании производительности они переходили туда-сюда, между которыми один был быстрее другого, и только на миллисекунды.
Глядя на закулисный код, вы действительно не видите никакой разницы. Единственная разница в IL, который 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.Empty в первый раз, и мне пришлось потратить некоторое время на поиск в Google, чтобы выяснить, действительно ли это одно и то же.
string.Empty
? Знаете ли вы, что ""
вы впервые увидели?
Эта тема довольно старая и длинная, поэтому извините, если это поведение было упомянуто где-то еще. (И укажите мне на ответ, который охватывает это)
Я нашел разницу в поведении компилятора, если вы используете 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 кодируется цветом иначе, чем строка. Что важно для читабельности. Кроме того, строчные буквы обычно используются для переменных и типов, что не имеет большого значения, но String.Empty - это константа, а не переменная или тип.
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 Type при доступе статические методы, свойства и поля: String.Empty
или Int32.TryParse(...)
илиDouble.Epsilon
Я всегда использую ключевые слова C # при объявлении новых экземпляров: int i = 0;
илиstring foo = "bar";
Я редко использую необъявленные строковые литералы, так как мне нравится иметь возможность сканировать код, чтобы объединить их в повторно используемые именованные константы. В любом случае компилятор заменяет константы на литералы, так что это скорее способ избежать магических строк / чисел и придать им немного больше значения с помощью имени. Плюс изменить значения проще.
Любой из первых двух будет приемлем для меня. Я бы избежал последнего, потому что относительно легко ввести ошибку, поместив пробел между кавычками. Эту конкретную ошибку было бы трудно обнаружить наблюдением. При условии отсутствия опечаток, все семантически эквивалентны.
[РЕДАКТИРОВАТЬ]
Кроме того , вы можете всегда использовать либо string
или String
для последовательности, но это только мне.
Я лично был свидетелем "", приводящего к (незначительным) проблемам дважды. Однажды это произошло из-за ошибки начинающего разработчика, плохо знакомого с командным программированием, а другая была простой опечаткой, но факт использовал string.Empty избежал бы обеих проблем.
Да, это в значительной степени суждение, но когда язык дает вам несколько способов сделать что-то, я склоняюсь к тому, который обладает наибольшим контролем над компилятором и самым сильным соблюдением времени компиляции. Это не "". Это все о выражении конкретных намерений.
Если вы введете string.EMpty или Strng.Empty, компилятор сообщит вам, что вы ошиблись. Немедленно. Он просто не скомпилируется. Как разработчик, вы ссылаетесь на конкретное намерение, которое компилятор (или другой разработчик) не может никоим образом неверно истолковать, а если вы сделаете это неправильно, вы не сможете создать ошибку.
Если вы наберете «», когда имеете в виду «» или наоборот, компилятор с радостью сделает то, что вы сказали. Другой разработчик может или не сможет найти ваши конкретные намерения. Ошибка создана.
Задолго до string.Empty я использовал стандартную библиотеку, которая определяла константу EMPTY_STRING. Мы по-прежнему используем эту константу в операторах case, где string.Empty не допускается.
Когда бы ни было возможно, заставьте компилятор работать на вас, и исключите возможность человеческой ошибки, независимо от того, насколько она мала. ИМО, это козыри "читабельности", как цитировали другие.
Специфика и время компиляции. Это то, что на ужин.
Компилятор должен сделать их все равно в долгосрочной перспективе. Выберите стандарт, чтобы ваш код было легко читать, и придерживайтесь его.
Я просто смотрел какой-то код, и этот вопрос всплыл у меня в голове, который я прочитал некоторое время назад. Это, безусловно, вопрос читабельности.
Рассмотрим следующий код 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
... мой уровень обслуживания низкий ;-)
Пустая строка похожа на пустой набор, просто имя, которое все используют для вызова ""
. Также в формальных языках строки, созданные из алфавита с нулевой длиной, называются пустой строкой. И set, и string имеют специальный символ для этого. Пустая строка: ε и пустое множество: ∅. Если вы хотите поговорить об этой строке нулевой длины, вы назовете ее пустой строкой, чтобы все точно знали, на что вы ссылаетесь. Теперь, если вы называете ее пустой строкой, почему бы не использовать ее string.Empty
в коде, она показывает, что намерение является явным. Недостатком является то, что он не является константой и поэтому не доступен везде, как в атрибутах. (Это не константа по некоторым техническим причинам, см. Справочный источник.)
Я предпочитаю, ""
потому что это короче и String.Empty
решает проблему, которая не существует.