Linhas de interpolação de cadeia longa em C # 6

134

Descobri que, embora a interpolação de strings seja realmente boa quando aplicada às chamadas Format da string da minha base de código existente, dado o limite de coluna geralmente preferido, a string rapidamente se torna muito longa para uma única linha. Especialmente quando as expressões interpoladas são complexas. Com uma string de formato, você tem uma lista de variáveis ​​que podem ser divididas em várias linhas.

var str = string.Format("some text {0} more text {1}",
    obj1.property,
    obj2.property);

Alguém tem algum meio preferido de quebrar essas linhas?

Suponho que você poderia fazer algo como:

var str = $"some text { obj1.property }" +
  " more text { obj2.property };
Jeremiah Gowdy
fonte
1
Na minha experiência, é melhor evitar interpolar expressões complexas. Em vez disso, extraia uma variável nesse caso. Se você fizer isso, e você terminar onde houver novas linhas dentro de suas strings, normalmente ele se ajustará bem.
Markijbema
2
Estou confuso com esta pergunta. Eu só quero uma multilinha $""que funcione como@""
Coronel Panic
2
Coronel Panic, a pergunta é sobre como quebrar longas linhas de interpolação para não violarmos os requisitos de largura da coluna, sem introduzir feeds de linha na própria string literal. $ @ "" é ótimo, mas qualquer nova linha introduzida nela estará na string literal.
Jeremiah Gowdy 5/05
4
Perigo: $"some text { obj1.property }" + " more text { obj2.property }";não faz o que você pensa que faz. Somente a primeira metade dessa expressão é uma sequência interpolada; é então concatenado com o não -interpolated string literal" more text { obj2.property }"
Bacar
1
Para suportar \ t \ r \ n em $ @, veja a pergunta stackoverflow.com/questions/51991713/…
M.Hassan

Respostas:

198

Você pode dividir a linha em várias linhas, mas eu não diria que a sintaxe parece mais agradável.

Você precisa usar a $@sintaxe para usar uma sequência literal interpolada e pode colocar novas linhas dentro dos {...}parâmetros, como este:

string s = $@"This is all {
    10
    } going to be one long {
    DateTime.Now
    } line.";

A string acima não conterá nenhuma nova linha e terá conteúdo como este:

Todos esses 10 serão uma longa linha 01.08.2015 23.49.47.

(nota, formato norueguês)

Agora, tendo dito isso, eu não pararia de usar string.Format. Na minha opinião, algumas dessas expressões de interpolação de strings parecem realmente boas, mas as mais complexas começam a ficar muito difíceis de ler. Considerando que, a menos que você use FormattableString, o código será compilado em uma chamada de String.Formatqualquer maneira, eu diria que continue indo String.Formatonde faz sentido.

Lasse V. Karlsen
fonte
Resposta sólida. Tenho certeza de que tudo se FormattableStringresume também a uma ligação String.Format.
Alex Booker
8
Essa resposta me ajudou a descobrir como fazer exatamente o oposto disso. Obrigado pela $@""sintaxe!
Bobson
@AlexBooker É mais complexo que isso. Você não pode fazer FormattableString.Invarian($"Hello {name}" + \n "are you the owner of {pet}?");isso porque mescla as duas seqüências interpoladas em uma única sequência simples.
ANeves 30/01/19
Novas linhas e guias são respeitadas em seqüências verbais interpoladas. Digite o seguinte na janela interativa do C # e a sequência resultante será formatada :. > var name = "Simon"; var templateName = "How to interpolate a verbatim string"; var now = DateTime.UtcNow;. var output = $@"Hi {name}, This template is a demo of {templateName}. It was ran at {now.ToString("o")}"; > output. A saída é"Hi Simon,\r\nThis template is a demo of How to interpolate a verbatim string.\r\n\r\nIt was ran at 2020-01-24T15:49:35.6678353Z"
Enzoaeneas 24/01
1
@Enzoaeneas Acho que você superestimou o suporte à formatação nos comentários, mas entendo e concordo com o que você está dizendo.
Lasse V. Karlsen
61

Você pode combinar $e @reunir para obter interpolação de string e literal de string de várias linhas:

var str = $@"some text { obj1.property }
     more text { obj2.property }";

Mas isso dará a você um NewLinepersonagem no meio, portanto pode não ser o que você deseja.

MarcinJuraszek
fonte
3
Mas @ não coloca realmente o feed de linha no literal?
Jeremiah Gowdy
5
Faz. Atualizei minha resposta para dizer isso explicitamente.
MarcinJuraszek
Não apenas uma nova linha, mas também as guias iniciais da nova linha. Para representar corretamente o formato real da string ao usar $@"no visual studio, você deve iniciar cada nova linha na extremidade esquerda do editor de texto.
GDS
Com esta solução você não pode usar por exemplo, \ r \ n na string
Johan Franzen
22

Enquanto o OP pediu outra coisa, espero que muitas pessoas que leem essa pergunta desejem uma interpolação multilinha $""que funcione assim @"". Para fazer isso, use$@""

$@"Height: {height}
Width: {width}
Background: {background}"
Coronel Panic
fonte
3
Ele não quer novas linhas na saída, apenas o próprio código para embrulhar em linhas diferentes
Martin Capodici
7
Ele deixou claro que essa resposta era destinada ao público que chega pesquisando como executar seqüências multilinhas usando a sintaxe de interpolação de cadeias.
Brandon Bonds
2

É isso:

var str = $"some text { obj1.property }" +
          $" more text { obj2.property }";

Observe o segundo $no$"..." + $"..."

CallMeLaNN
fonte
18
Observe que isso fará duas chamadas para String.Format e também criará três strings na memória (Lado A, Lado B e A + B) #
9115 Kevin Kalitowski
1
Isso não impediria o uso de um FormattableStringelenco na sequência concatenada?
binki
4
Atualmente, em muitas implementações, rodando em uma CPU de GHz com Gb de memória, uma chamada extra e uma sequência adicional não causam problemas de desempenho. Problemas de desempenho serão causados, por exemplo, pelo uso de um algoritmo de O (n2). Eu acho injusto rebaixar esse cara.
Johan Franzén
1

Eu usei StringBuilder em ToString () substituído como um exemplo.

    // return employee data
    public override string ToString()
    {
        StringBuilder buffer = new StringBuilder();
        buffer.AppendLine($"Number: {EmployeeNumber}");
        buffer.AppendLine($"Name: {EmployeeName}");
        buffer.AppendLine($"Address: {PostalAddress}");
        buffer.AppendLine($"Phone: {PhoneNumber}");
        buffer.AppendLine($"Age: {EmployeeAge}");
        buffer.AppendLine($"Gender: {EmployeeGender}");
        buffer.AppendLine($"Status: {EmployeeStatus}");
        buffer.AppendLine($"Manager: {EmployeeManager}");
        buffer.AppendLine($"Start: {EmployeeStartDate.ToShortDateString()}");
        return buffer.ToString();
    }
Christopher Govender
fonte
então por que não buffer.AppendFormat("{0}Number: {1}", Environment.NewLine, EmployeeNumber);???
TS