Что такое @ перед строкой в ​​C #?

604

Это вопрос .NET для C # (или, возможно, VB.net), но я пытаюсь выяснить, в чем разница между следующими объявлениями:

string hello = "hello";

против

string hello_alias = @"hello";

Распечатка на консоли не имеет значения, свойства длины одинаковы.

Klaw
источник
Пожалуйста, ознакомьтесь с моим предложением по IDE для Visual Studio для улучшения форматирования дословных строк (и добавьте голосование): Отступить многострочные дословные строки .
Оливье Жако-
Чтобы было понятно, приведенные выше примеры дают точно такой же результат с или без @.
Миро Дж

Ответы:

768

Он помечает строку как буквальный строковый литерал - все, что в строке обычно интерпретируется как escape-последовательность , игнорируется.

Так "C:\\Users\\Rich"же, как@"C:\Users\Rich"

Есть одно исключение: для двойной кавычки необходима escape-последовательность. Чтобы избежать двойных кавычек, нужно поместить две двойные кавычки в ряд. Например, @""""оценивает в ".

Ричард Эв
источник
1
@RichardEverett Я понял ответ, но я сомневаюсь, что на самом деле используется эта функция?
Арун
24
@Arun Это действительно полезно, когда имеешь дело со строками, содержащими такие вещи, как определения регулярных выражений, которые часто нуждаются в экранировании самих вещей
Джеймс Торп
25
+ многострочный контент
Jaider
4
вам также все равно придется удвоить скобки, {{если вы хотите использовать обычную скобку в string.Formatвызове.
Дейв Кузино
4
@RichardEverett очень полезен для создания многострочных строковых литералов без необходимости разбивать строку на части.
Джон Мотт
256

Это дословно строковый литерал . Это означает, что экранирование не применяется. Например:

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

Здесь verbatimи regularсодержание одинаковое.

Это также позволяет многострочное содержимое - что может быть очень удобно для SQL:

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

Один бит экранирования, который необходим для дословных строковых литералов, состоит в получении двойной кавычки ("), которую вы делаете, удваивая ее:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Джон Скит
источник
16
Это также позволяет использовать зарезервированные слова как имена переменных и прочее. Как public int GetValueOrDefault (int @default);
Свиш
5
Свиш: Верно, но не имеет отношения к этому конкретному вопросу.
Джон Скит
63

'@' Также имеет другое значение: размещение его перед объявлением переменной позволяет использовать зарезервированные ключевые слова в качестве имен переменных.

Например:

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

Я нашел только одно или два законных использования для этого. В основном в ASP.NET MVC, когда вы хотите сделать что-то вроде этого:

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

Который будет производить ссылку HTML, как:

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

В противном случае вам придется использовать «Класс», который не является зарезервированным ключевым словом, но заглавная буква «С» не соответствует стандартам HTML и выглядит неправильно.

JulianR
источник
18

Поскольку вы также явно просили VB, позвольте мне добавить, что этот синтаксис дословной строки не существует в VB, только в C #. Скорее, все строки дословно в VB (за исключением того факта, что они не могут содержать разрывы строк, в отличие от дословных строк C #):

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

Последовательности перехода не существуют в VB (за исключением удвоения символа кавычки, как в дословных строках C #), что усложняет некоторые вещи. Например, чтобы написать следующий код в VB, вам нужно использовать конкатенацию (или любой другой способ построения строки)

string x = "Foo\nbar";

В VB это будет написано следующим образом:

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

( &является оператором конкатенации строк VB. +может также использоваться.)

Конрад Рудольф
источник
1
О боже, это звучит раздражающе ... еще больше рад, что я сейчас использую C #: p
Svish
Вы не можете вставлять разрывы строк в строковые литералы VB, даже если вы можете в дословные строковые литералы C #. Таким образом, они не одинаковы.
Джои
@Svish, подожди, я что-то упустил? Это не обман для VB вообще. Действительно, это одно место, где VB выигрывает C #. Лучше сделать это таким образом и явным образом объединить символы новой строки и специальные символы, а не бросать все специальные символы между "и ".
Пейсер
@Pacerier Это чепуха. Как только вы выполняете больше, чем обычную обработку строк, необходимые средства построения строк становятся необходимыми, и способность к краткой обработке специальных символов является главной среди них. Однако есть и C #, и VB String.Format, что позволяет это делать. На самом деле, я бы сейчас никогда не писал "x" & Environment.NewLine, а вместо этого всегда использовал String.Format("x{0}", Environment.Newline)и т. Д. Тем не менее, C # здесь удобнее.
Конрад Рудольф
@KonradRudolph, я бы выбрал "x" & nl & nlили "x" + nl + nlили "x" . $nl . $nlлюбой день закончился "x\n\n". Также "x" + bs + bs окончен "x\\\\". И "x" + q + qболее "x\"\""/ "x""""". Теперь String.Formatчто касается другой проблемы, не связанной со сравнением, которое мы делаем выше.
Pacerier
10

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

C # поддерживает две формы строковых литералов: обычные строковые литералы и дословные строковые литералы.

Обычный строковый литерал состоит из нуля или более символов, заключенных в двойные кавычки, как в «hello», и может включать как простые escape-последовательности (например, \ t для символа табуляции), так и шестнадцатеричные и escape-последовательности Unicode.

Строковый литерал состоит из символа @, за которым следует символ двойной кавычки, ноль или более символов и закрывающий символ двойной кавычки. Простой пример - @ "привет". В дословном строковом литерале символы между разделителями интерпретируются дословно, единственное исключение составляет кавычка-escape-последовательность. В частности, простые escape-последовательности и шестнадцатеричные и Unicode escape-последовательности не обрабатываются в дословных строковых литералах. Строковый литерал может содержать несколько строк.

Эд Гинесс
источник
9

Это дословная строка, которая изменяет правила экранирования. Единственный символ, который теперь экранируется, это ", экранированный в" ". Это особенно полезно для путей к файлам и регулярных выражений:

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

так далее

Марк Гравелл
источник
Разве вы не пропустили @ в вашем примере, Марк? Или это по умолчанию, когда я использую var? Немного смущен ...
Дирк Воллмар
1
ОК - это действительно очень странно. Интересно, редактор их жевал?
Марк Гравелл
9

Скопировано из MSDN :

Во время компиляции дословные строки преобразуются в обычные строки с одинаковыми escape-последовательностями. Поэтому, если вы просматриваете дословную строку в окне наблюдения отладчика, вы увидите экранирующие символы, которые были добавлены компилятором, а не дословную версию из вашего исходного кода. Например, дословная строка @"C:\files.txt"появится в окне просмотра как "C:\\files.txt".

aanund
источник
Это типичный вводящий в заблуждение фрагмент документации Microsoft, ИМХО! То, что выше указано в качестве конечного результата, является правильным, но основная истина заключается в том, что строки в C # преобразуются в соответствующую последовательность байтов (или многобайтовые коды символов). C # допускает два разных способа представления базовой строки, с @ "..." или "...". Отладчик всегда выбирает путь «...» и не может определить, какой из них использовался в первую очередь. (Последовательности перехода, такие как \ n или "", относятся только к программированию и отображению строкового представления уровня и никогда не сохраняются в базовой строке!)
MikeBeaton
8

Помещение @перед строкой позволяет использовать специальные символы, такие как обратную косую черту или двойные кавычки, без необходимости использовать специальные коды или escape-символы.

Таким образом, вы можете написать:

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

вместо:

string path = "C:\\My path\\";
Presidenten
источник
3

Объяснение простое. Чтобы представить строку "string\", компилятору нужен, "string\\"потому что \это escape-символ. Если вы используете @"string\"вместо этого, вы можете забыть о \\.

Рэй Ву
источник