string.Empty vs null.Qual você usa?

84

Recentemente, um colega de trabalho me disse para não usar string.Emptyao definir uma variável de string, mas usar nullporque polui a pilha?

Ele diz não faça

string myString=string.Empty; mas faça string mystring=null;

Isso realmente importa? Eu sei que string é um objeto, então meio que faz sentido.

Eu sei que é uma pergunta boba, mas qual é a sua opinião?

user712923
fonte
1
Não tenho certeza de por que você faria qualquer um ... você pode dar um pouco mais do código que estava discutindo como exemplo?
stusmith
não há código. Pedi ao meu colega para olhar para algo que eu estava depurando e ele disse como regra geral "não use string.empty" defina-o como nulo conforme vai para a pilha. Pessoalmente, sempre usei string. já que a hora de lançamento deveria ser a coisa certa a ser usada, em vez de "".
user712923
O que quero dizer é ... string.Empty, ""e nullsão todos valores constantes, mas são todos 'simples' o suficiente para que eu não consiga ver por que você atribui um a uma variável. Se você precisa capturar uma outvariável, por que não apenas usar string myString;?
stusmith
8
Hoje em dia, argumentos sobre tópicos como esse, que não são focados em legibilidade e semântica e focam em micro-otimizações absurdas, são fracos, na melhor das hipóteses. Use o que significa a coisa correta para o seu contexto. (por exemplo, se você souber que alguém não tem um nome do meio, você usa String.Empty; se você não sabe se alguém tem ou não um nome do meio, você usa null). Então, uma vez que você tenha o significado correto, escreva o código de uma forma que seja claramente correta e de fácil manutenção.
jason

Respostas:

110

nulle Emptysão muito diferentes, e não sugiro alternar arbitrariamente entre eles. Mas também não tem nenhum "custo" extra, uma vez queEmpty é uma única referência fixa (você pode usá-la quantas vezes quiser).

Não há "poluição" na pilha causada por um ldsfld - essa preocupação é .... louca. Carregar um nullé indiscutivelmente marginal mais barato, mas pode causar exceções nulo de referência se você não for cuidadoso sobre como verificar o valor.

Pessoalmente, eu não uso nenhum ... Se eu quiser uma string vazia, eu uso ""- simples e óbvio. Internar significa que também não há sobrecarga por uso.


No nível IL, a diferença aqui entre "" e Vazio é apenas ldstr vs ldsfld - mas ambos fornecem a mesma referência de string interna. Além disso, em versões mais recentes do .NET, o JIT tem interceptação direta desses, produzindo a referência de string vazia sem realmente fazer uma pesquisa de campo estático. Basicamente, não há exatamente nenhuma razão para se preocupar de qualquer maneira, exceto a legibilidade. Eu apenas uso "".

Marc Gravell
fonte
5
@ user712923 se ele voltar com alguma preocupação concreta, adoraria ouvi-la
Marc Gravell
4
@Marc: ASAIK "" cria um objeto onde string.Empty não é .. verifique isto e isto . Tem a ver com piscina interna de string ....
Disse Jalal
7
@Hemal: String.IsNullOrEmpty ()
Vinko Vrsalovic
1
+1 para usar em ""vez de um código padrão seis vezes maior. Quem defendeu esse absurdo ?! @Jalal A postagem de Brad Abrams está seriamente desatualizada e se o compilador ainda não otimizar esses dois códigos para fazer o mesmo, que vergonha para a Microsoft! Mas não é nosso trabalho consertar o trabalho deles. E, de fato, não precisamos: No segundo link, Lasse (nos comentários) comparou as saídas de montagem da comparação com qualquer uma das variantes: elas são idênticas.
Konrad Rudolph
1
@Konrad: Um exemplo é o que acontece quando concatenam strings constantes: a classe string usa pool interno, então quando você faz uma nova string, a classe verifica se a string já está no pool e então se não a adicionou ao pool. Por isso quando ""ele vai pesquisar em todo o pool para verificar se já está lá ou não, e é assim que ao usar o string.Empty;ele vai usar aquele valor predefinido e a pesquisa não existirá mais. a classe também expôs estes métodos: string.Intern/IsInternedverifique isto
Jalal Said
34

Não 'polui a pilha', não há razão técnica, mas há uma grande diferença entre definir uma variável para uma referência a um objeto (mesmo que seja uma string vazia) e null. Eles não são a mesma coisa e devem ser usados ​​de maneiras diferentes.

nulldeve ser usado para indicar a ausência de dados, string.Empty(ou "") para indicar a presença de dados, na verdade algum texto vazio. Existe um caso específico em que você não tem certeza do que é mais apropriado?

Editar, exemplos adicionados:

  • Você pode usar string.Emptycomo o postfix padrão para o nome de uma pessoa (a maioria das pessoas não tem PhD, por exemplo)

  • Você pode usar nullpara uma opção de configuração que não foi especificada no arquivo de configuração. Nesse caso, string.Emptyseria usado se a opção config estivesse presente, mas o valor configurado desejado fosse uma string vazia.

Kieren Johnstone
fonte
Eu nunca pensei dessa forma, tenho que admitir. Considerando o que você acabou de dizer, você se importa em me dar um exemplo. Sei que sua explicação é autoexplicativa, mas ainda assim ... obrigado
usuário712923
2
Bem, a única razão para escolher um ou outro é com base no local onde você o usaria. string.EmptyOu seja, use ou ""quando quiser usar uma string vazia e nullquando quiser indicar que não há dados. Você pode usar string.Emptycomo o postfix padrão para o nome de uma pessoa (a maioria das pessoas não tem PhD, por exemplo) - e nullpara uma opção de configuração que não foi especificada no arquivo de configuração. Nesse segundo caso, string.Emptyseria usado se a opção config estivesse presente, mas o valor configurado desejado fosse uma string vazia.
Kieren Johnstone
@Kieren Johnstone, se um não tem nome postfix, por que não usar nullpara indicar "sem postfix"?
OfirD
8

Eles são diferentes como outros já responderam.

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

O problema com o gerenciamento de strings vazias vs. strings nulas está se tornando um problema quando você precisa persistir em um arquivo simples ou transferi-lo por meio de comunicações, então acho que pode ser útil para quem visita esta página dar uma boa solução para esse problema particular.

Com o propósito de salvar strings em um arquivo ou comunicações:
você provavelmente desejará converter a string em bytes.
uma boa prática que recomendo é adicionar 2 segmentos de bytes de cabeçalho à string convertida.

segmento 1 - meta informação que é armazenada em 1 byte e descreve o comprimento do próximo segmento.

segmento 2 - contém o comprimento da string a ser salva.

exemplo:
string "abcd" - para simplificar, vou convertê-la usando o codificador ASCII e obter {65,66,67,68}.
calcular o segmento 2 produzirá 4 - portanto, 4 bytes são o comprimento da string convertida.
calcular o segmento 1 resultará em 1 - já que apenas 1 byte foi usado para armazenar as informações de comprimento da string convertida (que era 4, ou seja, se fosse 260 eu obteria 2)

A nova faixa de bytes agora será {1,4,65,66,67,68}, que pode ser salva em um arquivo.

O benefício em relação ao assunto é que se eu tivesse uma string vazia para salvar eu obteria da conversão um array vazio de bytes no comprimento de 0 e depois de calcular os segmentos eu acabaria tendo {1,0} que pode ser salvo e posteriormente carregado e interpretado de volta em uma string vazia. Por outro lado, se eu tivesse um valor nulo em minha string, acabaria tendo apenas {0} como minha matriz de bytes para salvar e, novamente, quando carregado, poderia ser interpretado de volta como nulo.

Existem mais benefícios, como saber qual o tamanho a ser carregado ou acumulado se você jag várias strings.

Voltando ao assunto - isso irá .. bem, meio que poluirá a pilha, já que os mesmos princípios descritos estão sendo usados ​​por qualquer sistema para diferenciar nulos de vazios .. então sim string.Empty leva mais memória do que nulo, embora eu não chame de poluição .. é apenas mais 1 byte.

GY
fonte
1

Foi respondido até a morte, mas nulo significa nenhum valor, não inicializado. string.Empty significa "" (uma string em branco) como indicado no MSDN.

A maneira mais segura de verificar se há uma string vazia ou nula é usando string.IsNullOrEmpty.

Carlos A Merighe
fonte
-2

FWIW, achei essa mixagem ""e String.Emptynão funciona:

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"

Em particular, se você usa $.trimpara obter o valor de um campo de entrada DOM vazio, então compare com String.Empty, você obtém false. Não tenho certeza do porquê, mas aí está. Agora uso apenas em ""todos os lugares para consistência.

user1072817
fonte
1
Sim. É por isso que todos devemos ter o hábito de verificar .Length==0ou usar.Compare()
zanlok
14
Esta pergunta é sobre c # not js
Cole Johnson