Devo usar .ToString () ao concatenar variáveis ​​de seqüência de caracteres e números inteiros em C #?


19
int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

Devo usar:

string expression = "Expression: " + a + " + " + b + " = " + sum;

ou

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

É recomendável usar ToString()ao concatenar stringe int?


6
Em a + "" + b + ""ou "" + a + b + "", não importa: é tudo concatenação de strings. Em a + b + ""ela faz questão: ae bsão adicionados em primeiro lugar.
Tim S.

4
Nota lateral: No VB.NET, essa ambiguidade é evitada com um operador explícito de concatenação de strings : "Expression: " + alançará um erro de tempo de compilação (com a opção Strict On), "Expression: " & aexecutará a concatenação de strings.
Heinzi

O primeiro código resultará em boxe (int para Int32), o segundo não. O segundo é obviamente mais rápido.
Random Alphabets

Respostas:


33

ToString uso

Não, você não deve usar ToStringaqui.

A concatenação de strings transforma automaticamente as não strings em strings, o que significa que suas duas variantes são quase idênticas:

Quando um ou ambos os operandos são do tipo string, os operadores de adição predefinidos concatenam a representação de strings dos operandos.

Origem: C # Language Specification: operador de adição, MSDN .

Por outro lado, o primeiro (sem ToString):

  • É mais curto para escrever,
  • É mais curto para ler,
  • É mais fácil de manter e:
  • mostra exatamente a intenção do autor: concatenar strings.

Então, prefira o primeiro.

Sob o capô

O que também é interessante é ver o que acontece sob o capô. Uma das maneiras de ver isso é assistir o código IL no LINQPad. Este programa:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

é traduzido para o seguinte IL:

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

Está vendo isso System.String.Concat? Isso significa que o código original também pode ser escrito assim, o que se traduz exatamente na mesma IL:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

Ao ler a documentação destring.Concat(object[]) , você pode aprender que:

O método concatena cada objeto em args chamando o ToStringmétodo sem parâmetros desse objeto; não adiciona nenhum delimitador.

Isso significa que ToStringé redundante. Além disso:

String.Empty é usado no lugar de qualquer objeto nulo na matriz.

Que lida bem com o caso em que alguns dos operandos são nulos (consulte a nota de rodapé 1).

Enquanto no último exemplo, a concatenação foi traduzida string.Concat, também deve-se destacar as otimizações do compilador:

var a = "Hello " + "World";

é traduzido para:

ldstr       "Hello World"
stloc.0

Por outro lado:

var a = string.Concat("Hello ", "World");

é traduzido para:

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

Outras alternativas

É claro que existem outras maneiras de concatenar representações de seqüência de caracteres de objetos em C #.

  1. StringBuilderé usado quando você precisa executar muitas operações de concatenação e ajuda a reduzir o número de cadeias intermediárias criadas. Decidir se você deve usar uma StringBuilderou uma concatenação comum pode não ser fácil. Use um criador de perfil ou pesquise respostas relevantes no Stack Overflow.

    O uso StringBuildertem uma grande desvantagem em dificultar a leitura e a manutenção do código. Para casos simples como o da sua pergunta, StringBuildernão é apenas prejudicial à legibilidade do código, mas também inútil em termos de desempenho.

  2. string.Join deve ser usado quando você precisar adicionar delimitadores.

    Obviamente, nunca use string.Joincom um delimitador vazio para concatenar seqüências de caracteres.

  3. string.Formatpode ser usado quando o modelo de sequência é preferível à concatenação de sequência. Um dos casos em que você pode preferir é quando a mensagem pode ser localizada, conforme sugerido na resposta por kunthet.

    O uso de string.Formatvárias desvantagens o torna inadequado para casos simples como o seu:

    • Com espaços reservados simples "{0}", geralmente não está claro qual parâmetro vai para onde. É frequente reverter os parâmetros por engano ou esquecer um. Felizmente, o C # 6 finalmente introduz a interpolação de cadeias que resolve esse problema.

    • O desempenho do tempo de execução pode diminuir. Claro, não assuma que string.Formaté sempre mais lento. Se o desempenho importa, meça duas abordagens e determine qual é mais rápida com base nos resultados reais, em vez de suposições.

    • O código é um pouco mais longo para escrever, mais longo para ler e mais difícil de manter, embora isso seja extremamente pequeno e não deva incomodar muito.


Difference A diferença aparece quando um dos objetos está null. Sem ToString, a nullé substituído por uma sequência vazia. Com ToString, um NullReferenceExceptioné lançado.


1
Por exatamente esse motivo (comportamento imprevisível), concatenar strings com o +é considerado uma prática ruim na maioria dos idiomas. Neste caso, eu usaria string.Concat, em muitos casos, string.Formaté melhor. Certamente não é Pythonic +, e como o PEP 3101 também %é desencorajado a favor str.format.
Arda Xi

2
Substituir uma string vazia por nullrealmente "manipular bem"? Bem, não é tão ruim quanto "na Error Resume Next" ...
Deduplicator

Sob o capô, se você concatenar sem chamar .ToString (), o boxe acontecerá ... e Concat(object[])será usado em vez de Concat(string[]). Então "string " + inão é realmente idêntico a"string " + i.ToString()
Random Alphabets

@RandomAlphabets: ponto válido. No entanto, a diferença é simplesmente a localização ToString()do código: OP em um caso, System.String.Concata implementação no outro caso. Portanto, a resposta permanece válida: não escreva o código que não tem benefício.
Arseni Mourzenko

15

Em vez disso, você deve usar o formatador de string. É mais fácil formatar seu número em representação ou localização de string. por exemplo:

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

Mais informações no MSDN .

No entanto, o formatador de strings é menos legível (e talvez também o desempenho) que a concatenação de strings.


6
Gostaria de explicar por que essa opção é melhor?
World Engineer

@ WorldEngineer: atualizei a explicação.
kunthet

12
Não conheço todos os outros, mas acho isso mais legível. Talvez porque eu cresci com C, onde s [n] printf é a única opção realista para esse tipo de código.
Jules

2
Mas dessa maneira, três fontes de erros são substituídas por uma. Quando você adiciona algo à string, 1) precisa alterar a string de formato, 2) não se esqueça de adicionar um novo parâmetro na lista, 3) tenta escolher o local correto na lista onde o novo parâmetro deve ser colocado.
Ruslan

2
Apenas queira entrar em contato e informar sobre o próximo recurso de interpolação de strings no C # 6. Você escreverá "Expressão: \ {a} + \ {b} = \ {sum}" para obter o mesmo resultado. codeproject.com/Articles/846566/…
cwap

-2

Se você usar +concatenação, ele próprio usará o String.Concatmétodo A sequência em si não expõe um operador +.

por exemplo:

int i = 10;
string str = "hello" + i;

é compilado em:

int i = 10;
object o1 = "hello";
object o2 = i; // Note boxing
string str = string.Concat(o1, o2);

Se você ligar diretamente ToString, isso evitará o boxe e a Concat(string, string)sobrecarga. Portanto, a ToStringchamada será um pouco mais eficiente, embora não seja significativa o suficiente. É melhor você seguir o exemplo que achar mais legível.


2
este parece pontos meramente repetir feito e explicado na resposta anterior : "String concatenação transforma automaticamente não-strings em cordas ..."
mosquito
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.