В чем разница между строкой.Пустой и "" (пустая строка)?



в .NET, в чем разница между String.Empty и "", и они взаимозаменяемы, или есть некоторые основные проблемы ссылки или локализации вокруг равенства, что String.Empty гарантирует, что это не проблема?

1084   15  

15 ответов:

в .NET до версии 2.0,"" создает объект, в то время как string.Empty создает объект ref, которая составляет string.Empty более эффективным.

в версии 2.0 и позже .NET, все вхождения "" обратитесь к тому же строковому литералу, что означает "" эквивалентно .Empty, но все же не так быстро, как .Length == 0.

.Length == 0 самый быстрый вариант, но .Empty делает для немного более чистого кода.

посмотреть Спецификация .NET для получения дополнительной информации.

в чем разница между строкой.Пусто и "", А они есть взаимозаменяемо

string.Empty - это поле только для чтения, тогда как "" является константой времени компиляции. Места, где они ведут себя по-разному:

значение параметра по умолчанию в C# 4.0 или выше

void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
    //... implementation
}

выражение Case в операторе switch

string str = "";
switch(str)
{
    case string.Empty: // Error: A constant value is expected. 
        break;

    case "":
        break;

}

аргументы

[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression 
//        or array creation expression of an attribute parameter type

предыдущие ответы были правильными для .NET 1.1 (посмотрите на дату публикации, которую они связали: 2003). Начиная с .NET 2.0 и более поздних версий, по существу нет никакой разницы. JIT в конечном итоге будет ссылаться на один и тот же объект в куче в любом случае.

согласно спецификации C#, раздел 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(против.71).аспн

каждый строковый литерал не обязательно приводит к новому экземпляру строки. Когда два или дополнительные строковые литералы, эквивалентные в соответствии с оператором равенства строк (раздел 7.9.7), отображаются в одной сборке, эти строковые литералы ссылаются на один и тот же экземпляр строки.

кто-то даже упоминает об этом в комментариях к посту Брэда Абрама

таким образом, практический результат "" против строки.Пусто-это ноль. JIT поймет это в конце концов.

Я обнаружил, лично, что JIT намного умнее меня, и поэтому я стараюсь не получить слишком умно с микро-оптимизаций компилятора подобное. JIT будет разворачиваться для циклов (), удалять избыточный код, встроенные методы и т. д. лучше и в более подходящее время, чем я или компилятор C# могли когда-либо ожидать перед рукой. Пусть Джит делает свою работу:)

String.Empty Это только для чтения

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

string foo()
{
    return "foo" + "";
}
string bar()
{
    return "bar" + string.Empty;
}

сгенерируйте этот IL

.method private hidebysig instance string foo() cil managed
{
    .maxstack 8
    L_0000: ldstr "foo"
    L_0005: ret 
}
.method private hidebysig instance string bar() cil managed
{
    .maxstack 8
    L_0000: ldstr "bar"
    L_0005: ldsfld string [mscorlib]System.String::Empty
    L_000a: call string [mscorlib]System.String::Concat(string, string)
    L_000f: ret 
}

приведенные выше ответы технически правильны, но то, что вы действительно можете использовать, для лучшей читаемости кода и наименьших шансов на исключение строку.IsNullOrEmpty (s)

использовать String.Empty, а не "".

это больше для скорости, чем использование памяти, но это полезный совет. Этот "" является литералом, поэтому будет действовать как литерал: при первом использовании это создается и для следующих целей возвращается его ссылка. Единственный экземпляр "" будут сохранены в памяти независимо от того, сколько раз мы используй его! Я не вижу здесь никаких штрафов за память. проблема в том, что каждый раз "" используется, выполняется цикл сравнения, чтобы проверить, если "" уже находится в пуле интернирования. С другой стороны, String.Empty это ссылка на "" хранится в зоне памяти.NET Framework. String.Empty указывает на тот же адрес памяти для VB.NET и C# приложения. Так зачем искать ссылку каждый раз, когда вам нужно "" когда у вас есть эта ссылка в String.Empty?

ссылки: String.Empty vs ""

строку.Пустой не создает объект, в то время как "" делает. Разница, как указано здесь, это тривиально.

все экземпляры "" являются одинаковыми, интернированными строковыми литералами (или они должны быть). Таким образом, вы действительно не будете бросать новый объект в кучу каждый раз, когда вы используете"", но просто создаете ссылку на один и тот же, интернированный объект. Сказав это, я предпочитаю строку.Пустой. Я думаю, что это делает код более читабельным.

Это просто не имеет значения!

некоторые прошлые обсуждения этого:

http://www.codinghorror.com/blog/archives/000185.html

http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx

http://blogs.msdn.com/brada/archive/2003/04/27/50014.aspx

Я предпочитаю использовать String.Empty, а не "" по одной простой, но не очевидной причиной: "" и "" Не то же самое, первый на самом деле имеет 16 символов нулевой ширины в нем. Очевидно, что ни один компетентный разработчик не собирается вставлять символы нулевой ширины в свой код, но если они туда попадут, это может быть кошмар для обслуживания.

Примечания:

  • Я U+FEFF в этом примере.

  • не уверен если так собирается съесть эти символы, но попробуйте сами с одним из многих символов нулевой ширины

  • Я пришел к этому только благодаря https://codegolf.stackexchange.com/

string mystring = "";
ldstr ""

ldstr помещает новую ссылку на объект в строковый литерал, хранящийся в метаданных.

string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty

ldsfld помещает значение статического поля в стек оценки

Я предпочитаю использовать String.Empty вместо "" потому что ИМХО это яснее и меньше VB-иш.

исходя из этого с точки зрения Entity Framework: EF версии 6.1.3, похоже, обрабатывают строку.Пустой и "" по-разному при проверке.

строку.Пустой обрабатывается как нулевое значение для целей проверки и выдаст ошибку проверки, если она используется в обязательном (атрибутированном) поле; где as "" пройдет проверку и не выдаст ошибку.

эта проблема может быть решена в EF 7+. Ссылка: - https://github.com/aspnet/EntityFramework/issues/2610 ).

Edit: [Required (AllowEmptyStrings = true)] решит эту проблему, разрешив строку.Пусто для проверки.

Начиная Со Строки.Пусто не является константой времени компиляции вы не можете использовать его в качестве значения по умолчанию в определении функции.

public void test(int i=0,string s="")
    {
      // Function Body
    }

все здесь дали хорошие теоретические разъяснения. У меня были такие же сомнения. Поэтому я попробовал базовое кодирование на нем. И я нашел разницу. Вот в чем разница.

string str=null;
Console.WriteLine(str.Length);  // Exception(NullRefernceException) for pointing to null reference. 


string str = string.Empty;
Console.WriteLine(str.Length);  // 0

поэтому кажется, что " Null "означает абсолютно пустую &" строку.Пустой " означает, что он содержит какое-то значение, но он пуст.

Comments

    Ничего не найдено.