Was ist das @ vor einem String in C #?

604

Dies ist eine .NET-Frage für C # (oder möglicherweise VB.net), aber ich versuche herauszufinden, was der Unterschied zwischen den folgenden Deklarationen ist:

string hello = "hello";

vs.

string hello_alias = @"hello";

Das Ausdrucken auf der Konsole macht keinen Unterschied, die Längeneigenschaften sind gleich.

Klaw
quelle
Weitere Informationen zur wörtlichen Formatierung von Zeichenfolgen finden Sie in meinem Vorschlag für die Visual Studio-IDE (und stimmen Sie ihn ab): Mehrzeilige wörtliche Zeichenfolgen einrücken .
Olivier Jacot-Descombes
Um klar zu sein, die obigen Beispiele liefern mit oder ohne genau das gleiche Ergebnis @.
Miro J.

Antworten:

768

Es markiert die Zeichenfolge als wörtliches Zeichenfolgenliteral - alles in der Zeichenfolge, das normalerweise als Escape-Sequenz interpretiert wird, wird ignoriert.

So "C:\\Users\\Rich"ist das gleiche wie@"C:\Users\Rich"

Es gibt eine Ausnahme: Für das doppelte Anführungszeichen wird eine Escape-Sequenz benötigt. Um einem doppelten Anführungszeichen zu entgehen, müssen Sie zwei doppelte Anführungszeichen hintereinander setzen. Zum Beispiel @""""wertet auf aus ".

Richard Ev
quelle
1
@RichardEverett Ich habe die Antwort verstanden. Aber ich bezweifle, dass diese Funktion tatsächlich verwendet wird.
Arun
24
@Arun Es ist wirklich nützlich, wenn es um Zeichenfolgen geht, die Dinge wie Definitionen regulärer Ausdrücke enthalten, bei denen häufig Dinge selbst maskiert werden müssen
James Thorpe
25
+ mehrzeiliger Inhalt
Jaider
4
Sie müssen auch noch Klammern verdoppeln, {{wenn Sie eine normale Klammer in einem string.FormatAnruf verwenden möchten .
Dave Cousineau
4
@RichardEverett ist sehr nützlich, um mehrzeilige String-Literale zu erstellen, ohne die Linie in Teile zerlegen zu müssen.
John Mott
256

Es ist ein wörtliches String-Literal . Dies bedeutet, dass die Flucht nicht angewendet wird. Zum Beispiel:

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

Hier verbatimund regularhaben den gleichen Inhalt.

Es ermöglicht auch mehrzeilige Inhalte - was für SQL sehr praktisch sein kann:

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

Das einzige bisschen, das für wörtliche Zeichenfolgenliterale erforderlich ist, besteht darin, ein doppeltes Anführungszeichen (") zu erhalten, das Sie durch Verdoppeln ausführen:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Jon Skeet
quelle
16
Es erlaubt auch die Verwendung reservierter Wörter als Variablennamen und -material. Wie public int GetValueOrDefault (int @default);
Svish
5
Svish: Richtig, aber ohne Bezug zu dieser speziellen Frage.
Jon Skeet
63

Ein '@' hat auch eine andere Bedeutung: Wenn Sie es vor eine Variablendeklaration stellen, können Sie reservierte Schlüsselwörter als Variablennamen verwenden.

Zum Beispiel:

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

Ich habe nur ein oder zwei legitime Verwendungszwecke dafür gefunden. Hauptsächlich in ASP.NET MVC, wenn Sie so etwas tun möchten:

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

Welches würde einen HTML-Link erzeugen wie:

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

Andernfalls müssten Sie 'Klasse' verwenden, was kein reserviertes Schlüsselwort ist, aber der Großbuchstabe 'C' entspricht nicht den HTML-Standards und sieht einfach nicht richtig aus.

JulianR
quelle
18

Da Sie auch explizit nach VB gefragt haben, möchte ich nur hinzufügen, dass diese wörtliche Zeichenfolgensyntax in VB nicht existiert, sondern nur in C #. Vielmehr sind alle Zeichenfolgen in VB wörtlich (mit Ausnahme der Tatsache, dass sie im Gegensatz zu wörtlichen C # -Strings keine Zeilenumbrüche enthalten können):

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

Escape-Sequenzen existieren in VB nicht (mit Ausnahme der Verdoppelung des Anführungszeichens, wie in wörtlichen C # -Strings), was einige Dinge komplizierter macht. Um beispielsweise den folgenden Code in VB zu schreiben, müssen Sie die Verkettung (oder eine der anderen Möglichkeiten zum Erstellen einer Zeichenfolge) verwenden.

string x = "Foo\nbar";

In VB würde dies wie folgt geschrieben werden:

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

( &Ist der VB-String-Verkettungsoperator. +Kann auch verwendet werden.)

Konrad Rudolph
quelle
1
Oh mein
Gott
Sie können keine Zeilenumbrüche in VB-Zeichenfolgenliterale einbetten, obwohl Sie dies in die wörtlichen Zeichenfolgenliterale von C # tun können. Sie sind also nicht gleich.
Joey
@Svish, warte, fehlt mir etwas? Dies ist überhaupt kein Nachteil für VB. In der Tat ist dies ein Ort, an dem VB C # gewinnt. Es ist besser, dies auf diese Weise zu tun und die Zeilenumbrüche und Sonderzeichen explizit zu verknüpfen, anstatt alle Sonderzeichen zwischen "und zu werfen ".
Pacerier
@ Pacerier Das ist Unsinn. Sobald Sie mehr als nur eine triviale Zeichenfolgenverarbeitung durchführen, sind ordnungsgemäße Funktionen zum Erstellen von Zeichenfolgen unabdingbar, und die Fähigkeit, Sonderzeichen präzise zu behandeln, gehört zu den wichtigsten. Sowohl C # als auch VB haben dies jedoch String.Format, was dies ermöglicht. Tatsächlich würde ich jetzt nie schreiben "x" & Environment.NewLineund stattdessen immerString.Format("x{0}", Environment.Newline) usw. verwenden . Dennoch ist C # hier bequemer.
Konrad Rudolph
@KonradRudolph, ich würde wählen "x" & nl & nloder "x" + nl + nloder "x" . $nl . $nljeden Tag vorbei "x\n\n". Auch "x" + bs + bs vorbei "x\\\\". Und "x" + q + qüber "x\"\""/ "x""""". Nun String.Format, das ist ein weiteres Problem, das nichts mit dem Vergleich zu tun hat, den wir oben machen.
Pacerier
10

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

C # unterstützt zwei Formen von String-Literalen: reguläre String-Literale und wörtliche String-Literale.

Ein reguläres Zeichenfolgenliteral besteht aus null oder mehr Zeichen in doppelten Anführungszeichen, wie in "Hallo", und kann sowohl einfache Escape-Sequenzen (z. B. \ t für das Tabulatorzeichen) als auch hexadezimale und Unicode-Escape-Sequenzen enthalten.

Ein wörtliches Zeichenfolgenliteral besteht aus einem @ -Zeichen, gefolgt von einem doppelten Anführungszeichen, null oder mehr Zeichen und einem abschließenden doppelten Anführungszeichen. Ein einfaches Beispiel ist @ "Hallo". In einem wörtlichen Zeichenfolgenliteral werden die Zeichen zwischen den Trennzeichen wörtlich interpretiert, wobei die einzige Ausnahme eine Anführungszeichen-Escape-Sequenz ist. Insbesondere werden einfache Escape-Sequenzen sowie hexadezimale und Unicode-Escape-Sequenzen nicht in wörtlichen String-Literalen verarbeitet. Ein wörtliches Zeichenfolgenliteral kann mehrere Zeilen umfassen.

Ed Guiness
quelle
9

Dies ist eine wörtliche Zeichenfolge, die die Escape-Regeln ändert. Das einzige Zeichen, das jetzt maskiert wird, ist ", maskiert nach". Dies ist besonders nützlich für Dateipfade und Regex:

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

usw

Marc Gravell
quelle
Vermissen Sie nicht das @ in Ihrem Beispiel, Marc? Oder ist es die Standardeinstellung, wenn ich var verwende? Wenig verwirrt ...
Dirk Vollmar
1
OK - das ist wirklich sehr, sehr seltsam. Ich frage mich, ob der Herausgeber sie gekaut hat.
Marc Gravell
9

Von MSDN kopiert :

Zur Kompilierungszeit werden wörtliche Zeichenfolgen in gewöhnliche Zeichenfolgen mit denselben Escape-Sequenzen konvertiert. Wenn Sie also eine wörtliche Zeichenfolge im Debugger-Überwachungsfenster anzeigen, werden die vom Compiler hinzugefügten Escape-Zeichen angezeigt, nicht die wörtliche Version aus Ihrem Quellcode. Beispielsweise wird die wörtliche Zeichenfolge @"C:\files.txt"im Überwachungsfenster als angezeigt "C:\\files.txt".

aanund
quelle
Welches ist ein typischer irreführender Teil der Microsoft-Dokumentation, IMHO! Was oben als Endergebnis angegeben ist, ist korrekt, aber die zugrunde liegende Wahrheit ist, dass Zeichenfolgen in C # in die relevante Folge von Bytes (oder Mehrbyte-Zeichencodes) konvertiert werden. C # ermöglicht zwei verschiedene Arten der Darstellung der zugrunde liegenden Zeichenfolge mit @ "..." oder "...". Der Debugger wählt immer den "..." Weg und kann nicht sagen, welcher überhaupt verwendet wurde. (Escape-Sequenzen wie \ n oder "" sind nur für die Programmierung und Darstellung von Zeichenfolgen auf Anzeigeebene relevant und werden niemals in der zugrunde liegenden Zeichenfolge gespeichert!)
MikeBeaton
8

Wenn Sie ein @Zeichen vor eine Zeichenfolge setzen, können Sie Sonderzeichen wie Backslash oder doppelte Anführungszeichen verwenden, ohne Sondercodes oder Escapezeichen verwenden zu müssen.

So können Sie schreiben:

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

anstatt:

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

Die Erklärung ist einfach. Um die Zeichenfolge darstellen "string\", muss der Compiler , "string\\"da \ist ein Escape - Zeichen. Wenn Sie @"string\"stattdessen verwenden, können Sie vergessen \\.

Ray Wu
quelle