Qual é o @ na frente de uma string em C #?

604

Esta é uma pergunta do .NET para C # (ou possivelmente VB.net), mas estou tentando descobrir qual é a diferença entre as seguintes declarações:

string hello = "hello";

vs.

string hello_alias = @"hello";

Imprimir no console não faz diferença, as propriedades de comprimento são as mesmas.

Klaw
fonte
Por favor, veja (e vote) minha sugestão para o Visual Studio IDE para obter uma melhor formatação de sequência literal: Recuar sequências verbais múltiplas de várias linhas .
Olivier Jacot-Descombes
Para ficar claro, os exemplos acima estão produzindo exatamente o mesmo resultado com ou sem @.
31519 Miro J.

Respostas:

768

Ele marca a string como literal literal - qualquer coisa na string que normalmente seria interpretada como uma sequência de escape é ignorada.

Então "C:\\Users\\Rich"é o mesmo que@"C:\Users\Rich"

Há uma exceção: é necessária uma sequência de escape para as aspas duplas. Para escapar de aspas duplas, é necessário colocar duas aspas duplas em uma linha. Por exemplo, @""""avalia como ".

Richard Ev
fonte
1
@ RichardEverett eu entendi a resposta, mas minha dúvida é qual é o uso real desse recurso?
Arun
24
@Arun É muito útil quando se lida com cordas contendo coisas como definições de expressão regular que muitas vezes precisam coisas para ser escapou-se
James Thorpe
25
+ conteúdo de várias linhas
Jaider
4
você também precisará dobrar o aparelho {{se quiser usar um aparelho comum em uma string.Formatchamada.
Dave Cousineau
4
@RichardEverett é muito útil para criar literais de strings de várias linhas sem precisar dividir a linha em pedaços.
John Mott #
256

É uma string literal literal . Isso significa que escapar não é aplicado. Por exemplo:

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

Aqui verbatime regulartem o mesmo conteúdo.

Ele também permite conteúdo de várias linhas - o que pode ser muito útil para SQL:

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

O único ponto de escape necessário para literais de string literal é obter aspas duplas ("), que você faz dobrando-a:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Jon Skeet
fonte
16
Também permite usar palavras reservadas como nomes de variáveis ​​e outras coisas. Como public int GetValueOrDefault (int @default);
Svish
5
Svish: Verdadeiro, mas não relacionado a essa pergunta específica.
9119 Jon Skeet
63

Um '@' também tem outro significado: colocá-lo na frente de uma declaração de variável permite que você use palavras-chave reservadas como nomes de variáveis.

Por exemplo:

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

Eu encontrei apenas um ou dois usos legítimos para isso. Principalmente no ASP.NET MVC, quando você deseja fazer algo assim:

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

O que produziria um link HTML como:

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

Caso contrário, você teria que usar 'Class', que não é uma palavra-chave reservada, mas o 'C' maiúsculo não segue os padrões HTML e simplesmente não parece certo.

JulianR
fonte
18

Como você solicitou explicitamente o VB também, deixe-me acrescentar que essa sintaxe de string literal não existe no VB, apenas em C #. Em vez disso, todas as strings são verbatim no VB (exceto pelo fato de que não podem conter quebras de linha, diferentemente das strings verbatim do C #):

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

As seqüências de escape não existem no VB (exceto pela duplicação do caractere de citação, como nas seqüências de caracteres verbais em C #), o que torna algumas coisas mais complicadas. Por exemplo, para escrever o código a seguir no VB, você precisa usar a concatenação (ou qualquer outra maneira de construir uma string)

string x = "Foo\nbar";

No VB, isso seria escrito da seguinte maneira:

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

( &é o operador de concatenação de cadeias de caracteres VB. +poderia igualmente ser usado.)

Konrad Rudolph
fonte
1
Oh meu, que os sons chato ... ainda mais feliz que eu estou usando C # agora: p
Svish
Você não pode incorporar quebras de linha em literais de cadeia de caracteres VB, mesmo que seja possível em literais de cadeia de caracteres literal do C #. Portanto, eles não são os mesmos.
Joey
@ Skish, espera, estou faltando alguma coisa? Este não é um golpe para o VB. De fato, este é um lugar em que o VB ganha C #. É melhor fazê-lo dessa maneira e concatenar explicitamente as novas linhas e os caracteres especiais, em vez de lançar todos os caracteres especiais entre o "e ".
Pacerier
@ Pacerier Isso é um absurdo. Assim que você faz mais do que o processamento trivial de strings, as instalações apropriadas para construção de strings são indispensáveis, e a capacidade de manipular concisamente caracteres especiais é a principal delas. No entanto, tanto o C # quanto o VB possuem String.Format, o que permite fazer isso. Na verdade, agora eu nunca escreveria "x" & Environment.NewLinee, em vez disso, sempre usaria String.Format("x{0}", Environment.Newline)etc. Ainda assim, o C # é mais conveniente aqui.
Konrad Rudolph
@KonradRudolph, eu escolheria "x" & nl & nlou "x" + nl + nlou "x" . $nl . $nlqualquer dia mais "x\n\n". Também "x" + bs + bs acabou "x\\\\". E "x" + q + qmais "x\"\""/ "x""""". Agora String.Format, esse é outro problema não relacionado à comparação que estamos fazendo acima.
Pacerier 06/04
10

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

O C # suporta duas formas de literais de cadeia: literais de cadeia regulares e literais de cadeia literal.

Um literal de cadeia regular consiste em zero ou mais caracteres entre aspas duplas, como em "olá", e pode incluir seqüências de escape simples (como \ t para o caractere de tabulação) e seqüências de escape hexadecimais e Unicode.

Um literal literal de sequência consiste em um caractere @ seguido por um caractere de aspas duplas, zero ou mais caracteres e um caractere de aspas duplas de fechamento. Um exemplo simples é @ "olá". Em uma string literal literal, os caracteres entre os delimitadores são interpretados literalmente, a única exceção sendo uma sequência de escape de citação. Em particular, sequências de escape simples e seqüências de escape hexadecimais e Unicode não são processadas em literais de string literal. Um literal literal de cadeia de caracteres pode abranger várias linhas.

Ed Guiness
fonte
9

Esta é uma string literal e altera as regras de escape - o único caractere que agora é escapado é ", escapou para" ". Isso é especialmente útil para caminhos de arquivos e regex:

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

etc

Marc Gravell
fonte
Você não está sentindo falta do @ no seu exemplo, Marc? Ou é o padrão quando eu uso var? Pouco confuso ...
Dirk Vollmar
1
OK - isso é muito, muito estranho. Será que o editor os mastigou?
Marc Gravell
9

Copiado do MSDN :

Em tempo de compilação, seqüências textuais são convertidas em seqüências comuns com as mesmas seqüências de escape. Portanto, se você exibir uma sequência literal na janela de inspeção do depurador, verá os caracteres de escape que foram adicionados pelo compilador, não a versão literal do código-fonte. Por exemplo, a sequência literal @"C:\files.txt"aparecerá na janela de inspeção como "C:\\files.txt".

aanund
fonte
Qual é uma típica peça enganosa da documentação da Microsoft, IMHO! O que afirma acima como resultado final está correto, mas a verdade subjacente é que as seqüências de caracteres em C # são convertidas na seqüência relevante de bytes (ou códigos de caracteres de bytes múltiplos). O C # permite duas maneiras diferentes de representar a cadeia subjacente, com @ "..." ou "...". O depurador sempre escolhe o caminho "..." e não pode saber qual foi usado em primeiro lugar. (Escape seqüências, como \ n "" ou só são relevantes para a programação e representação cadeia de nível de exibição, e nunca são armazenados na seqüência subjacente!)
MikeBeaton
8

Colocar @na frente de uma sequência permite usar caracteres especiais, como uma barra invertida ou aspas duplas, sem precisar usar códigos especiais ou caracteres de escape.

Então você pode escrever:

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

ao invés de:

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

A explicação é simples. Para representar a sequência "string\", o compilador precisa "string\\"porque \é um caractere de escape. Se você usar @"string\", pode esquecer \\.

Ray Wu
fonte