¿Cuál es la @ delante de una cadena en C #?

604

Esta es una pregunta .NET para C # (o posiblemente VB.net), pero estoy tratando de averiguar cuál es la diferencia entre las siguientes declaraciones:

string hello = "hello";

vs.

string hello_alias = @"hello";

Imprimir en la consola no hace ninguna diferencia, las propiedades de longitud son las mismas.

Klaw
fuente
Consulte (y vote a favor) mi sugerencia para el IDE de Visual Studio para un mejor formato de cadena textual: sangría de cadenas textuales de varias líneas .
Olivier Jacot-Descombes
Para ser claros, los ejemplos anteriores están produciendo exactamente el mismo resultado con o sin @.
Miro J.

Respuestas:

768

Marca la cadena como literal literal de la cadena: se ignora cualquier cosa en la cadena que normalmente se interpretaría como una secuencia de escape .

Entonces "C:\\Users\\Rich"es lo mismo que@"C:\Users\Rich"

Hay una excepción: se necesita una secuencia de escape para la comilla doble. Para escapar de una comilla doble, debe poner dos comillas dobles seguidas. Por ejemplo, @""""evalúa a ".

Richard Ev
fuente
1
@ RichardEverett Comprendí la respuesta, pero mi duda es ¿cuál es el uso real de esta función?
Arun
24
@Arun Es realmente útil cuando se trata de cadenas que contienen cosas como definiciones de expresiones regulares que a menudo necesitan que las cosas se escapen por sí mismas
James Thorpe
25
+ contenido multilínea
Jaider
44
también tendrá que duplicar las llaves {{si desea usar una llave normal en una string.Formatllamada.
Dave Cousineau
44
@RichardEverett es muy útil para crear literales de cadena de varias líneas sin tener que dividir la línea en pedazos.
John Mott
256

Es una cadena literal literal . Significa que no se aplica el escape. Por ejemplo:

string verbatim = @"foo\bar";
string regular = "foo\\bar";

Aquí verbatimy regulartienen los mismos contenidos.

También permite contenidos de varias líneas, lo que puede ser muy útil para SQL:

string select = @"
SELECT Foo
FROM Bar
WHERE Name='Baz'";

El único escape que es necesario para los literales de cadena textuales es obtener una comilla doble ("), lo que haces al duplicarlo:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Jon Skeet
fuente
16
También permite usar palabras reservadas como nombres de variables y otras cosas. Me gusta public int GetValueOrDefault (int @default);
Svish
55
Svish: Verdadero pero no relacionado con esta pregunta específica.
Jon Skeet
63

Una '@' también tiene otro significado: ponerla delante de una declaración de variable le permite usar palabras clave reservadas como nombres de variables.

Por ejemplo:

string @class = "something";
int @object = 1;

Solo he encontrado uno o dos usos legítimos para esto. Principalmente en ASP.NET MVC cuando quieres hacer algo como esto:

<%= Html.ActionLink("Text", "Action", "Controller", null, new { @class = "some_css_class" })%>

Lo que produciría un enlace HTML como:

<a href="/Controller/Action" class="some_css_class">Text</a>

De lo contrario, tendría que usar 'Clase', que no es una palabra clave reservada, pero la 'C' mayúscula no sigue los estándares HTML y simplemente no se ve bien.

JulianR
fuente
18

Dado que también solicitó explícitamente VB, permítanme agregar que esta sintaxis de cadena literal no existe en VB, solo en C #. Más bien, todas las cadenas son textuales en VB (excepto el hecho de que no pueden contener saltos de línea, a diferencia de las cadenas literales de C #):

Dim path = "C:\My\Path"
Dim message = "She said, ""Hello, beautiful world."""

Las secuencias de escape no existen en VB (excepto por la duplicación del carácter de comillas, como en las cadenas textuales de C #), lo que hace que algunas cosas sean más complicadas. Por ejemplo, para escribir el siguiente código en VB necesita usar concatenación (o cualquiera de las otras formas de construir una cadena)

string x = "Foo\nbar";

En VB esto se escribiría de la siguiente manera:

Dim x = "Foo" & Environment.NewLine & "bar"

( &es el operador de concatenación de cadenas VB. +igualmente podría usarse).

Konrad Rudolph
fuente
1
Oh, eso suena molesto ... aún más contento de estar usando C # ahora: p
Svish
No puede incrustar saltos de línea en los literales de cadena de VB, aunque puede hacerlo en los literales de cadena literales de C #. Por lo tanto, no son lo mismo.
Joey
@Svish, espera ¿me estoy perdiendo algo? Esto no es una estafa para VB en absoluto. De hecho, este es un lugar donde VB gana C #. Es mejor hacerlo de esta manera y concatenar explícitamente las nuevas líneas y los caracteres especiales en lugar de tirar todos los caracteres especiales entre el "y ".
Pacerier
@Pacerier Eso no tiene sentido. Tan pronto como realice más que un procesamiento trivial de cadenas, las instalaciones adecuadas para la creación de cadenas son indispensables, y la capacidad de manejar con precisión caracteres especiales son las más destacadas. Sin embargo, tanto C # como VB tienen String.Format, lo que permite hacer esto. De hecho, ahora nunca escribiría "x" & Environment.NewLine, y en su lugar siempre usaría String.Format("x{0}", Environment.Newline)etc. Aún así, C # es más conveniente aquí.
Konrad Rudolph
@KonradRudolph, elegiría "x" & nl & nlo "x" + nl + nlo "x" . $nl . $nlcualquier día sobre "x\n\n". También "x" + bs + bs terminado "x\\\\". Y "x" + q + qsobre "x\"\""/ "x""""". Ahora en cuanto a String.Format, ese es otro problema no relacionado con la comparación que estamos haciendo anteriormente.
Pacerier
10

http://msdn.microsoft.com/en-us/library/aa691090.aspx

C # admite dos formas de literales de cadena: literales de cadena regulares y literales de cadena literales.

Un literal de cadena regular consta de cero o más caracteres encerrados entre comillas dobles, como en "hola", y puede incluir tanto secuencias de escape simples (como \ t para el carácter de tabulación) como secuencias de escape hexadecimales y Unicode.

Un literal de cadena literal consiste en un carácter @ seguido de un carácter de comillas dobles, cero o más caracteres y un carácter de comillas dobles de cierre. Un ejemplo simple es @ "hola". En un literal de cadena literal, los caracteres entre los delimitadores se interpretan literalmente, la única excepción es una secuencia de escape entre comillas. En particular, las secuencias de escape simples y las secuencias de escape hexadecimales y Unicode no se procesan en literales de cadena literales. Un literal de cadena literal puede abarcar varias líneas.

Ed Guiness
fuente
9

Esta es una cadena literal, y cambia las reglas de escape: el único carácter que ahora se escapa es ", se escapó a" ". Esto es especialmente útil para rutas de archivos y expresiones regulares:

var path = @"c:\some\location";
var tsql = @"SELECT *
            FROM FOO
            WHERE Bar = 1";
var escaped = @"a "" b";

etc.

Marc Gravell
fuente
¿No te estás perdiendo la @ en tu ejemplo, Marc? ¿O es el valor predeterminado cuando uso var? Poco confundido ...
Dirk Vollmar
1
OK, eso es muy, muy extraño. Me pregunto si el editor los comió?
Marc Gravell
9

Copiado de MSDN :

En tiempo de compilación, las cadenas literales se convierten en cadenas ordinarias con las mismas secuencias de escape. Por lo tanto, si ve una cadena literal en la ventana de observación del depurador, verá los caracteres de escape que fueron agregados por el compilador, no la versión literal de su código fuente. Por ejemplo, la cadena literal @"C:\files.txt"aparecerá en la ventana de observación como "C:\\files.txt".

aanund
fuente
Que es una pieza engañosa típica de la documentación de Microsoft, en mi humilde opinión! Lo que indica lo anterior como resultado final es correcto, pero la verdad subyacente es que las cadenas en C # se convierten a la secuencia relevante de bytes (o códigos de caracteres de varios bytes). C # permite dos formas diferentes de representar la cadena subyacente, con @ "..." o "...". El depurador siempre elige la forma "...", y no puede saber cuál se utilizó en primer lugar. (Las secuencias de escape como \ n o "" solo son relevantes para la programación y la representación de cadenas de nivel de visualización, ¡y nunca se almacenan en la cadena subyacente!)
MikeBeaton
8

Poner un @frente a una cadena le permite usar caracteres especiales como una barra diagonal inversa o comillas dobles sin tener que usar códigos especiales o caracteres de escape.

Entonces puedes escribir:

string path = @"C:\My path\";

en vez de:

string path = "C:\\My path\\";
Presidenten
fuente
3

La explicación es simple. Para representar la cadena "string\", el compilador necesita "string\\"porque \es un carácter de escape. Si usa @"string\"en su lugar, puede olvidarse \\.

Ray Wu
fuente