string.format com variáveis ​​vs variáveis ​​embutidas

9

Quais são os prós / contras (se houver) em usar

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

versus

string output; 
int i = 10;
output = "the int is " + i;

Eu sempre usei o último exemplo, mas parece que uma boa maioria dos tutoriais online usa o exemplo string.format. Eu não acho que haja diferenças reais em termos de eficiência, meu pensamento inicial é que um codificador não precise continuar quebrando a string para inserir variáveis.

Jim
fonte
8
O principal motivo é que isso facilita muito a tradução, porque seu programa não precisa entender a maneira como diferentes idiomas constroem suas frases. Por exemplo, muitas expressões e frases em francês são invertidas em comparação com as traduções em inglês.
precisa saber é

Respostas:

22

Se você considera a tradução importante em seu projeto, a primeira sintaxe realmente ajudará.

Por exemplo, você pode ter:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

Observe também que suas variáveis ​​nem sempre podem estar no mesmo lugar na sentença com essa sintaxe:

static final string output_yoda = "{1} years {0} has.";
Alex Garcia
fonte
4
+1 para usar o Yoda-speak como um exemplo de sintaxe objeto-sujeito-verbo.
Mike Harris
11
Com o C #, temos uma nova opção:System.out.println($"{name} is {age} year's old.");
Berin Loritsch
@BerinLoritsch: que é completamente inutilizável para localização, infelizmente.
amigos estão
@BryanBoettcher, entendeu, mas eu não vi nada no OP dizendo que era isso que eles estavam tentando realizar.
Berin Loritsch
8

Confira a primeira resposta para /programming/4671610/why-use-string-format . Abrange tudo, na minha opinião, por que é melhor.

Além disso, cada assembly .NET possui um pool interno, contendo uma coleção de strings exclusivas. Quando seu código é compilado, todos os literais de seqüência de caracteres que você menciona no seu código são adicionados a esse pool. Se você tiver um código parecido com este:

"the int is " + i + " and the double is " + d

Isso torna duas cordas na piscina.

Se você tem:

"the int is {0} and the double is {1}"

Você tem apenas uma String no pool.

É um pouco mais complicado saber quando Strings são internadas e quando não são, porque o compilador possui alguma inteligência ao detectar Strings que talvez não precisem ser internadas algumas vezes ... Confira, por exemplo, este artigo que fornece mais informações sobre isso importam.

Edit: depois de desenterrar um pouco, encontrei uma resposta interessante para a pergunta Quando é melhor usar a concatenação String.Format vs string? . Em resumo, o autor da resposta com +30 votos apresenta um argumento convincente a favor da concatenação de String quando a localização não está envolvida.

Jalayn
fonte
2
Penso também, estilisticamente, que ressoa com pessoas, ou seja, pessoas como eu, que estão acostumadas a imprimir e correr de c.
Jonathan Henson
Eu gostaria de saber por que o voto negativo, a fim de corrigir minha resposta. Obrigado.
Jalayn
4

Eu prefiro a primeira maneira, porque ela me permite ver com precisão como a string será exibida quando for exibida. É muito fácil esquecer de adicionar um espaço ou adicionar um espaçamento extra ao anexar seqüências de caracteres.

Tenho certeza de que também há um benefício de desempenho para a primeira maneira, porque não é necessário criar as strings extras; mas essa não é minha principal preocupação.

John Kraft
fonte
2

Usando a primeira opção, você pode armazenar uma string de formato usada com frequência, reduzir a digitação necessária e facilitar a atualização da string em todos os lugares em que é usada. Basicamente, a primeira opção permite que o DRY seja implementado facilmente. Também é uma sintaxe muito melhor se várias variáveis ​​precisarem ser usadas em uma string, como você mencionou.

Ryathal
fonte
ahh entendo, acho que não pensei no exemplo: string.format ("o int é {0}. novamente é {0}", int);
Jim
1

Eu acho string.Format()que é mais fácil ver qual será exatamente o resultado (para que você não tenha problemas com espaços esquecidos ou algo assim), e também é mais fácil digitar e modificar.

Se você deseja formatar com simplicidade, usar o +operador plus pode ser mais fácil, mas costumo usá-lo apenas quando concatenar duas cadeias, não mais.

Para mostrar como string.Format()é mais fácil modificar, considere que você deseja adicionar um ponto final no final da frase no seu exemplo: passar de string.Format("The int is {0}", i)para string.Format("The int is {0}.", i)é apenas um caractere. Mas passar de "the int is " + ipara "the int is " + i + '.'é muito mais.

Outra vantagem string.Format()é que ele permite que você especifique facilmente o formato a ser usado, como string.Format("The int is 0x{0:X}.", i). Isso é ainda mais importante ao formatar a data.

Quanto à eficiência, string.Format()é mais provável que concatenações simples de cadeia de caracteres. Mas códigos como este provavelmente não estão em um caminho quente, por isso não importa. E se isso acontecer, você provavelmente estará melhor usando StringBuilder.

svick
fonte
string.Format usa internamente um StringBuilder de qualquer maneira #
Bryan Boettcher
1

Use o que torna seu código mais legível. Não se preocupe com o desempenho.

Para o seu exemplo abaixo, prefiro B porque é apenas mais legível. Mas as traduções de idiomas acima também fazem sentido. Não deixe que ninguém o force a usar string.Format, leia e aponte para o excelente blog de Jeff Atwoods no The Sad Tragedy of Micro Optimizations Theatre

UMA:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

versus

B:

string output; 
int i = 10;
output = "the int is " + i;
Makach
fonte
-1

Ref: Saída da string: formato ou concat em C #?

Considere este código.

É uma versão ligeiramente modificada do seu código.

  1. Eu removi o Console.WriteLine, pois é provavelmente poucas ordens de magnitude mais lentas do que o que estou tentando medir.
  2. Estou olhando o cronômetro antes do loop e parando logo depois, assim não perco a precisão se a função levar, por exemplo, 26,4 ticks para executar.
  3. A maneira como você dividiu o resultado pelo número de iterações estava errada. Veja o que acontece se você tiver 1000 milissegundos e 100 milissegundos. Nas duas situações, você receberá 0 ms depois de dividir por 1000000.
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

Esses são os meus resultados:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks
jp2code
fonte
11
Como isso responde aos aspectos de se o primeiro exemplo de código ou o segundo exemplo de código é um design melhor? Como um meio segundo nas iterações da 1M explica se esse é um código mais fácil para uma pessoa manter ou não?
Jim perguntou: "Quais são os prós e os contras?" Isso mostra que, em muitas iterações, String.Format é mais rápido.
Jp2code # 28/15
Você deve adicionar completamente isso à sua resposta em vez de deixá-lo como um bloco de código e diferenças em relação ao código do OP. Tal como está, sua resposta não responde à pergunta do OP em inglês. Veja as outras respostas. Seria possível remover todo o código deles e ainda ter uma resposta para a pergunta do OP.