Quel est le @ devant une chaîne en C #?

604

Il s'agit d'une question .NET pour C # (ou peut-être VB.net), mais j'essaie de comprendre quelle est la différence entre les déclarations suivantes:

string hello = "hello";

contre.

string hello_alias = @"hello";

L'impression sur la console ne fait aucune différence, les propriétés de longueur sont les mêmes.

Klaw
la source
Veuillez consulter (et voter positivement) ma suggestion pour l'IDE de Visual Studio pour un meilleur formatage des chaînes textuelles: indenter les chaînes textuelles multilignes .
Olivier Jacot-Descombes
Pour être clair, les exemples ci-dessus produisent exactement le même résultat avec ou sans @.
Miro J.

Réponses:

768

Il marque la chaîne comme un littéral de chaîne textuel - tout élément de la chaîne qui serait normalement interprété comme une séquence d'échappement est ignoré.

C'est "C:\\Users\\Rich"la même chose que@"C:\Users\Rich"

Il y a une exception: une séquence d'échappement est nécessaire pour le guillemet double. Pour échapper à un guillemet double, vous devez mettre deux guillemets consécutifs. Par exemple, @""""évalue à ".

Richard Ev
la source
1
@RichardEverett J'ai compris la réponse, mais mon doute est quelle est l'utilisation réelle de cette fonctionnalité?
Arun
24
@Arun C'est vraiment utile lorsque vous traitez des chaînes contenant des choses comme des définitions d'expressions régulières qui ont souvent besoin de s'échapper elles
James Thorpe
25
+ contenu multi-lignes
Jaider
4
vous devrez également doubler les accolades {{si vous souhaitez utiliser une accolade régulière dans un string.Formatappel.
Dave Cousineau
4
@RichardEverett est très utile pour créer des littéraux de chaîne multi-lignes sans avoir à couper la ligne en morceaux.
John Mott
256

C'est un littéral de chaîne textuel . Cela signifie que l'échappement n'est pas appliqué. Par exemple:

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

Ici verbatimet regularont le même contenu.

Il permet également un contenu multi-lignes - ce qui peut être très pratique pour SQL:

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

Le seul élément d'échappement nécessaire pour les littéraux de chaîne textuels est d'obtenir un guillemet double (") que vous faites en le doublant:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Jon Skeet
la source
16
Il permet également d'utiliser des mots réservés comme noms de variables et autres. Comme public int GetValueOrDefault (int @default);
Svish
5
Svish: Vrai mais sans rapport avec cette question spécifique.
Jon Skeet
63

Un «@» a également une autre signification: le placer devant une déclaration de variable vous permet d'utiliser des mots clés réservés comme noms de variable.

Par exemple:

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

Je n'ai trouvé qu'une ou deux utilisations légitimes pour cela. Principalement dans ASP.NET MVC lorsque vous voulez faire quelque chose comme ceci:

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

Ce qui produirait un lien HTML comme:

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

Sinon, vous devrez utiliser «Classe», qui n'est pas un mot clé réservé, mais le «C» majuscule ne suit pas les normes HTML et ne semble tout simplement pas correct.

JulianR
la source
18

Puisque vous avez explicitement demandé VB également, permettez-moi d'ajouter que cette syntaxe de chaîne textuelle n'existe pas en VB, uniquement en C #. Au contraire, toutes les chaînes sont textuelles en VB (sauf qu'elles ne peuvent pas contenir de sauts de ligne, contrairement aux chaînes textuelles C #):

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

Les séquences d'échappement n'existent pas en VB (à l'exception du doublement du caractère de citation, comme dans les chaînes textuelles C #), ce qui complique certaines choses. Par exemple, pour écrire le code suivant en VB, vous devez utiliser la concaténation (ou l'une des autres façons de construire une chaîne)

string x = "Foo\nbar";

En VB, cela serait écrit comme suit:

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

( &est l'opérateur de concaténation de chaînes VB. +pourrait également être utilisé.)

Konrad Rudolph
la source
1
Oh mon Dieu, cela semble ennuyeux ... encore plus heureux que j'utilise C # maintenant: p
Svish
Vous ne pouvez pas incorporer des sauts de ligne dans les littéraux de chaîne VB, même si vous le pouvez dans les littéraux de chaîne textuels de C #. Ce ne sont donc pas les mêmes.
Joey
@Svish, Attends, est-ce que je manque quelque chose? Ce n'est pas du tout un inconvénient pour VB. En effet, c'est un endroit où VB gagne C #. Il est préférable de le faire de cette façon et de concaténer explicitement les nouvelles lignes et les caractères spéciaux au lieu de jeter tous les caractères spéciaux entre le "et ".
Pacerier
@Pacerier C'est absurde. Dès que vous faites plus qu'un traitement de chaîne insignifiant, des installations de construction de chaîne appropriées sont indispensables, et la capacité de gérer de manière concise les caractères spéciaux est au premier rang de ceux-ci. Cependant, les deux C # et VB ont String.Format, ce qui permet de le faire. En fait, je n'écrirais plus jamais"x" & Environment.NewLine , et j'utiliserais toujoursString.Format("x{0}", Environment.Newline) etc. etc. Pourtant, C # est plus pratique ici.
Konrad Rudolph
@KonradRudolph, je choisirais "x" & nl & nlou "x" + nl + nlou "x" . $nl . $nln'importe quel jour "x\n\n". Aussi "x" + bs + bs terminé "x\\\\". Et "x" + q + qplus "x\"\""/ "x""""". Maintenant String.Format, c'est un autre problème sans rapport avec la comparaison que nous faisons ci-dessus.
Pacerier
10

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

C # prend en charge deux formes de littéraux de chaîne: les littéraux de chaîne standard et les littéraux de chaîne textuels.

Un littéral de chaîne régulière se compose de zéro ou plusieurs caractères entre guillemets, comme dans "bonjour", et peut inclure à la fois des séquences d'échappement simples (telles que \ t pour le caractère de tabulation) et des séquences d'échappement hexadécimales et Unicode.

Un littéral de chaîne textuelle se compose d'un caractère @ suivi d'un caractère guillemet double, de zéro ou plusieurs caractères et d'un caractère guillemet double de fermeture. Un exemple simple est @ "bonjour". Dans un littéral de chaîne textuel, les caractères entre les délimiteurs sont interprétés textuellement, la seule exception étant une séquence d'échappement-guillemet. En particulier, les séquences d'échappement simples et les séquences d'échappement hexadécimales et Unicode ne sont pas traitées dans les littéraux de chaîne textuels. Un littéral de chaîne textuelle peut s'étendre sur plusieurs lignes.

Ed Guiness
la source
9

Ceci est une chaîne textuelle, et modifie les règles d'échappement - le seul caractère qui est maintenant échappé est ", échappé à" ". Ceci est particulièrement utile pour les chemins de fichier et l'expression régulière:

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

etc

Marc Gravell
la source
Ne manquez-vous pas le @ dans votre exemple, Marc? Ou est-ce la valeur par défaut lorsque j'utilise var? Un peu confus ...
Dirk Vollmar
1
OK - c'est vraiment, vraiment étrange. Je me demande si l'éditeur les a croquées?
Marc Gravell
9

Copié à partir de MSDN :

Au moment de la compilation, les chaînes textuelles sont converties en chaînes ordinaires avec toutes les mêmes séquences d'échappement. Par conséquent, si vous affichez une chaîne textuelle dans la fenêtre de surveillance du débogueur, vous verrez les caractères d'échappement qui ont été ajoutés par le compilateur, pas la version textuelle de votre code source. Par exemple, la chaîne textuelle @"C:\files.txt"apparaîtra dans la fenêtre de surveillance sous la forme "C:\\files.txt".

aanund
la source
Ce qui est un élément trompeur typique de la documentation Microsoft, à mon humble avis! Ce que ce qui précède indique comme résultat final est correct, mais la vérité sous-jacente est que les chaînes en C # sont converties en la séquence d'octets appropriée (ou codes de caractères multi-octets). C # permet deux manières différentes de représenter la chaîne sous-jacente, avec @ "..." ou "...". Le débogueur choisit toujours la voie "...", et ne peut pas dire laquelle a été utilisée en premier lieu. (Les séquences d'échappement telles que \ n ou "" ne sont pertinentes que pour la programmation et la représentation des chaînes de niveau d'affichage, et ne sont jamais stockées dans la chaîne sous-jacente!)
MikeBeaton
8

Mettre un @devant une chaîne vous permet d'utiliser des caractères spéciaux tels qu'une barre oblique inversée ou des guillemets doubles sans avoir à utiliser de codes spéciaux ou de caractères d'échappement.

Vous pouvez donc écrire:

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

au lieu de:

string path = "C:\\My path\\";
Presidenten
la source
3

L'explication est simple. Pour représenter la chaîne "string\", le compilateur a besoin "string\\"car \est un caractère d'échappement. Si vous utilisez à la @"string\"place, vous pouvez oublier \\.

Ray Wu
la source