В чем разница между String.Empty и "" (пустая строка)? - PullRequest
272 голосов
/ 30 сентября 2008

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

Ответы [ 17 ]

6 голосов
/ 30 сентября 2008

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

4 голосов
/ 17 апреля 2015
string mystring = "";
ldstr ""

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

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

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

Я склонен использовать String.Empty вместо "", потому что ИМХО, он более понятен и меньше использует VB.

2 голосов
/ 31 января 2019

Эрик Липперт писал (17 июня 2013 г.):
"Первым алгоритмом, над которым я работал в компиляторе C #, был оптимизатор, который обрабатывает конкатенации строк . К сожалению, мне не удалось перенести эти оптимизации в кодовую базу Roslyn до того, как я ушел, надеюсь, кто-то доберется до этого!"

Вот некоторые результаты Roslyn x64 по состоянию на январь 2019 года. Несмотря на консенсусные замечания других ответов на этой странице, мне не кажется, что текущий JIT x64 рассматривает все эти случаи одинаково , когда все сказано и сделано.

Обратите внимание, в частности, однако, что только один из этих примеров на самом деле вызывает String.Concat, и я предполагаю, что это из-за неясных причин правильности (в отличие от контроля за оптимизацией). Другие различия, кажется, труднее объяснить.


default (String) + {default (String), "", String.Empty}

static String s00() => default(String) + default(String);
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    add  rsp,28h
    ret

static String s01() => default(String) + "";
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    add  rsp,28h
    ret

static String s02() => default(String) + String.Empty;
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    mov  rdx,rax
    test rdx,rdx
    jne  _L
    mov  rdx,rax
_L: mov  rax,rdx
    add  rsp,28h
    ret

"" + {default (String), "", String.Empty}

static String s03() => "" + default(String);
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    add  rsp,28h
    ret

static String s04() => "" + "";
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    add  rsp,28h
    ret

static String s05() => "" + String.Empty;
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    mov  rdx,rax
    test rdx,rdx
    jne  _L
    mov  rdx,rax
_L: mov  rax,rdx
    add  rsp,28h
    ret

String.Empty + {default (String), "", String.Empty}

static String s06() => String.Empty + default(String);
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    mov  rdx,rax
    test rdx,rdx
    jne  _L
    mov  rdx,rax
_L: mov  rax,rdx
    add  rsp,28h
    ret

static String s07() => String.Empty + "";
    mov  rax,[String::Empty]
    mov  rax,qword ptr [rax]
    mov  rdx,rax
    test rdx,rdx
    jne  _L
    mov  rdx,rax
_L: mov  rax,rdx
    add  rsp,28h
    ret

static String s08() => String.Empty + String.Empty;
    mov  rcx,[String::Empty]
    mov  rcx,qword ptr [rcx]
    mov  qword ptr [rsp+20h],rcx
    mov  rcx,qword ptr [rsp+20h]
    mov  rdx,qword ptr [rsp+20h]
    call F330CF60                 ; <-- String.Concat
    nop
    add  rsp,28h
    ret


Детали теста
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
AMD64 Release
[MethodImpl(MethodImplOptions.NoInlining)]
'SuppressJitOptimization' = false
2 голосов
/ 14 марта 2017

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

public void test(int i=0,string s="")
    {
      // Function Body
    }
2 голосов
/ 09 марта 2017

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

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

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

Редактировать: [Обязательный (AllowEmptyStrings = true)] решит эту проблему, позволив string.Empty для проверки.

1 голос
/ 07 мая 2019

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

Определите строки (колоризация переполнения стека не очень помогает, но в VS это более очевидно):

var i = 30;
var f = Math.Pi;
var s = "";
var d = 22.2m;
var t = "I am some text";
var e = string.Empty;
0 голосов
/ 21 января 2016

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

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


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

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

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