Líneas de interpolación de cuerdas largas en C # 6

134

He descubierto que, si bien la interpolación de cadenas es realmente agradable cuando se aplica a las llamadas de formato de cadenas de mi base de código existente, dado el límite de columna generalmente preferido, la cadena rápidamente se vuelve demasiado larga para una sola línea. Especialmente cuando las expresiones que se interpolan son complejas. Con una cadena de formato tiene una lista de variables que puede dividir en varias líneas.

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

¿Alguien tiene algún medio preferido para romper estas líneas?

Supongo que podrías hacer algo como:

var str = $"some text { obj1.property }" +
  " more text { obj2.property };
Jeremiah Gowdy
fuente
1
En mi experiencia, es mejor evitar interpolar expresiones complejas. Más bien extraer una variable en ese caso. Si hace eso, y se separa donde tiene nuevas líneas dentro de sus cadenas, generalmente encajará bien.
markijbema
2
Estoy confundido por esta pregunta. Solo quiero una línea múltiple $""que funcione como@""
Coronel Panic
2
Coronel Panic, la pregunta es cómo dividir largas líneas de interpolación para no violar los requisitos de ancho de columna, sin introducir avances de línea en el literal de la cadena. $ @ "" es genial, pero cualquier nueva línea introducida en ella estará en el literal de cadena.
Jeremiah Gowdy
44
Peligro: $"some text { obj1.property }" + " more text { obj2.property }";no hace lo que parece pensar que hace. Solo la primera mitad de esa expresión es una cadena interpolada; luego se concatena con el literal de cadena no interpolado" more text { obj2.property }"
bacar
1
Para admitir \ t \ r \ n en $ @ vea la pregunta stackoverflow.com/questions/51991713/…
M.Hassan

Respuestas:

198

Usted puede romper la línea en varias líneas, pero yo no diría que la buena apariencia de sintaxis más.

Debe usar la $@sintaxis para usar una cadena textual interpolada , y puede colocar nuevas líneas dentro de los {...}parámetros, de esta manera:

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

La cadena anterior no contendrá ninguna línea nueva y en realidad tendrá contenido como este:

Todos estos 10 serán una larga línea 01.08.2015 23.49.47.

(nota, formato noruego)

Ahora, habiendo dicho eso, no dejaría de usar string.Format. En mi opinión, algunas de estas expresiones de interpolación de cadenas se ven realmente bien, pero las más complejas comienzan a ser muy difíciles de leer. Teniendo en cuenta que, a menos que lo use FormattableString, el código se compilará en una llamada de String.Formattodos modos, yo diría que continúe con String.Formatlo que tiene sentido.

Lasse V. Karlsen
fuente
Respuesta sólida Estoy bastante seguro de que también se FormattableStringreduce a una llamada String.Format.
Alex Booker
8
Esta respuesta me ayudó a descubrir cómo hacer exactamente lo contrario de esto. Gracias por la $@""sintaxis!
Bobson
@ AlexBooker Es más complejo que eso. No puede hacerlo FormattableString.Invarian($"Hello {name}" + \n "are you the owner of {pet}?");porque combina las dos cadenas interpoladas en una sola cadena simple.
ANeves
Las nuevas líneas y pestañas se respetan en cadenas textuales interpoladas. Ingrese lo siguiente en la ventana interactiva de C # y se formateará la cadena resultante: > 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. La salida es"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
1
@ Enzoaeneas Creo que sobrevaloraste el soporte de formato en los comentarios, pero entiendo y estoy de acuerdo con lo que estás diciendo.
Lasse V. Karlsen
61

Puede combinar $y @juntos para obtener interpolación de cadena y literal de cadena de varias líneas:

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

Pero eso te dará un NewLinepersonaje intermedio, por lo que puede que no sea lo que quieres.

MarcinJuraszek
fuente
3
¿Pero no @ realmente pone el avance de línea en el literal?
Jeremiah Gowdy
55
Lo hace. Actualicé mi respuesta para decir explícitamente eso.
MarcinJuraszek
No solo una nueva línea, sino también las pestañas iniciales de la nueva línea. Para representar correctamente el formato de cadena real cuando se usa $@"en Visual Studio, debe comenzar cada nueva línea desde el extremo izquierdo del editor de texto.
GDS
Con esta solución no puede usar, por ejemplo, \ r y \ n en la cadena
Johan Franzén
22

Si bien OP solicitó algo más, espero que muchas personas que lean esta pregunta deseen una interpolación multilínea $""que funcione de la misma manera @"". Para hacer eso, use$@""

$@"Height: {height}
Width: {width}
Background: {background}"
Coronel Panic
fuente
3
No quiere nuevas líneas en la salida, solo el código en sí mismo para
ajustarse
77
Dejó en claro que esta respuesta estaba destinada a la audiencia que llega buscando cómo hacer cadenas de líneas múltiples utilizando la sintaxis de interpolación de cadenas.
Brandon Bonds
2

Eso es todo:

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

Tenga $en cuenta el segundo en el$"..." + $"..."

CallMeLaNN
fuente
18
Tenga en cuenta que esto hará dos llamadas a String.Format y también creará tres cadenas en la memoria (Lado A, Lado B y A + B)
Kevin Kalitowski
1
¿No le impediría usar un FormattableStringmolde en la cadena concatenada?
binki
44
En muchas implementaciones de hoy, ejecutar en una CPU de GHz con Gb de memoria, una llamada adicional y una cadena adicional no le dará problemas de rendimiento. Los problemas de rendimiento serán causados, por ejemplo, utilizando un algoritmo de O (n2). Creo que es injusto despreciar a este tipo.
Johan Franzén el
1

He usado StringBuilder dentro de ToString () anulado como ejemplo.

    // 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
fuente
entonces por qué no buffer.AppendFormat("{0}Number: {1}", Environment.NewLine, EmployeeNumber);???
TS