2012-08-30 9 views
6

Estoy empezando a aprender C#, y no entiendo por qué los literales de cadena regulares (es decir, " ") no pueden contener caracteres literales nuevos. (No estoy hablando de la secuencia de escape \n). Sé que debe usar literales literales literales (es decir, @" ") para cadenas de varias líneas, pero ¿por qué?¿Por qué las cadenas no literales no pueden contener líneas nuevas?

regular string produces "Newline in constant" errorverbatim string produces no error

no he visto que establece explícitamente que no se puede utilizar en cadenas regulares. Más que eso, excepto cuando se menciona de paso que puedo usar cadenas literales para esto, todo lo que he leído parece sugerir que los caracteres literales nuevos se permitirían en los literales regulares de las cadenas.

Beginning Visual C# 2010 y Code: Generating Multiline String Literals (Visual C#) muestran ejemplos de cadenas verbales multilínea sin más explicaciones.

Learning C# 3.0 dice esto:

En el lenguaje C#, espacios, tabulaciones y saltos de línea se considera que son espacios en blanco .... espacios en blanco extra es generalmente ignorado en las declaraciones de C#. ... La excepción a esta regla es que el espacio en blanco dentro de una cadena se trata como literal; no es ignorado

¿Es literal? Eso es lo que esperaría también, pero no es así.
Incluso incluye esta caja de punta:

Consejo
programadores de Visual Basic, tomen nota: en C#, la línea de fin de no tiene ningún significado especial. Las declaraciones terminan con punto y coma, no con caracteres de nueva línea. No hay carácter de continuación de línea porque no se necesita ninguno.

(que se dan cuenta de que esto está hablando de fuera de cadenas, pero ¿por qué habría de final de línea tienen un significado especial análisis dentro de una cadena si no lo hace fuera de una cadena?)

Tener finalmente encontré mi camino al string (C# Reference) en sí mismo, aún no obtuve ninguna idea:

Los literales de cadena pueden contener cualquier carácter literal. Secuencias de escape están incluidas. El siguiente ejemplo usa la secuencia de escape \\ para la barra diagonal inversa, \u0066 para la letra fy \n para la línea nueva.

Se dice que las secuencias de escape pueden ser utilizados, pero no dice que deben ser utilizados. ¿Los caracteres literales nuevos no están incluidos en "cualquier carácter literal"? Si tengo una cadena que contiene un carácter de tabulación literal en lugar de su secuencia de escape \t, no hay ningún error. Pero si tengo una línea nueva literal, obtengo un error. Incluso cambié las terminaciones de línea del archivo de \r\n a \n o \r sin efecto.


Obviamente, soy capaz de inferir a partir de ejemplos y de los errores de Visual Studio que se requiere una cadena pie de la letra si contiene un carácter de nueva línea literal, sino todo lo que he leído sugiere que no debería ser el caso . ¿Por qué la diferencia?

+0

Creo que es probablemente una de esas cosas "porque así es como funciona el lenguaje". Probablemente fue inspirado en otros lenguajes de los que vendrían los nuevos programadores de C#. Como mencionaste, puedes usar el prefijo @ para definir una constante de cadena literal. –

+0

@MikeChristensen Oh sí, y traté de escapar de la nueva línea literal con una barra invertida como la que he visto en C/C++. No hubo suerte allí, tampoco. – Wiseguy

Respuesta

5

Bueno, dispara. Justo cuando estaba presentando esto, encontré la respuesta.

¿Los caracteres literales nuevos no están incluidos en "cualquier carácter literal"?

Aparentemente, no, no lo son.

2.4.4.4 Character literals:

carácter literal:

'carácter'

personaje:

solo carácter

solo carácter:

Cualquier carácter excepto '(U + 0027), \ (U + 005C), y nueva línea de caracteres

+0

Sí. ¿Pero por qué no se incluyen caracteres de nueva línea en los literales de caracteres? –

+0

@ZaidMasud Las opciones de diseño del idioma están muy por encima del alcance de mi pregunta. Mi objeción fue simplemente que esta característica no estaba claramente definida, que, de hecho, aparentemente es. – Wiseguy

+0

Sí, la especificación es coherente. Más de una curiosa reflexión de mi parte. –

1

probable engañar de Why must C/C++ string literal declarations be single-line?

En pocas palabras, porque el lenguaje C no lo admite.

Un error tipográfico que deja una cadena literal sin cerrar arrastrará el resto del archivo como un único token, dejando al programador con un mensaje de error del compilador en la línea de "esperando un punto y coma en la línea xxx, columna yyy" donde la ubicación indicada es el final del archivo fuente.

La mayoría de las veces no se usan literales multilínea. Mejor hacerlos explícitos desde una perspectiva UX.

Además, en el entorno restringido en el que se desarrolló el lenguaje C en (8K PDP-11?), Sospecho que ese tipo de desbordamiento podría bloquear el compilador.

lenguaje

El C es compatible con el empalme literal, sin embargo, que es útil:

char *txt = "this is line 1\n" 
      "this is line 2\n" 
      "this is line 3\n" 
      ; 

También es compatible con la línea de empalme:

char *txt = "this is my\n\ 
multi-line string literal\n\ 
isn't it nice?\n" ; 

Características que deseo C# tenía.

+0

Sí, traté de empalmar también, fue en vano. Estaba un poco sorprendido por eso ya que, si la limitación es heredada de los antepasados ​​de la familia C, pensé que heredaría eso también. – Wiseguy

+0

Sí, el tipo de empalme parece que debería estar allí. El hecho de que uno puede concatenar con '+' quizás fue visto como una eliminación de la necesidad. –

1

C# (junto con C++, C, Java, lo que influyó en su sintaxis) tiene una regla muy simple para los espacios en blanco:

Puede hacer lo que quiera con él.

Esto permite formatear las cosas como quiera para el beneficio de la legibilidad. Ahora, un fanático de Python podría decir que la ventaja está sobrevalorada, pero es una ventaja que utilizamos.

Las nuevas líneas en cuerdas podrían estropear eso. Todo el Moreso si no está seguro de si la nueva línea en la fuente debe significar que insertamos "\u000D", "\u000A", "\u000A\u000D", "\u0085", "\u000B", "\u000C", "\u2028" o "\u2029" en la cadena, todos los cuales tienen la semántica de nueva línea y los primeros cuatro de que han sido la "única manera sensata de hacer una nueva línea del sistema diferente, todos los demás están equivocados".

Aún podría argumentarse que la desventaja de permitirlo está sobrevalorada. C# hace - después de todo, la forma de cadenas que son no como se podría esperar de C++, etc. lo permite.

+0

Me imaginé "¿qué importa?" siempre que la cadena termine con una cita de cierre (como es el caso de PHP, por ejemplo), pero es un buen punto sobre la ambigüedad del final de la línea. – Wiseguy

Cuestiones relacionadas