Що означає @ перед рядком у C #?


602

Це питання .NET для C # (або, можливо, VB.net), але я намагаюся з'ясувати, у чому різниця між наступними деклараціями:

string hello = "hello";

vs.

string hello_alias = @"hello";

Друк на консолі не має різниці, властивості довжини однакові.


Будь ласка, дивіться мою пропозицію щодо IDE Visual Studio щодо кращого дословного форматування рядків: відступ багаторядкових дослідних рядків .
Олів'є

Щоб було зрозуміло, наведені вище приклади дають точно такий же результат із або без @.
Miro J.

Відповіді:


767

Він позначає рядок як дослівний рядковий рядковий рядок - все в рядку, яке зазвичай інтерпретується як послідовність відходу , ігнорується.

Так "C:\\Users\\Rich"це те саме, що@"C:\Users\Rich"

Є один виняток: для подвійної лапки потрібна послідовність виходу. Щоб уникнути подвійної цитати, потрібно поставити дві подвійні лапки підряд. Наприклад, @""""оцінює до ".


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
Це також дозволяє використовувати зарезервовані слова як імена змінних та ін. Як і публічний 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>

Інакше вам доведеться використовувати "Class", яке не є зарезервованим ключовим словом, але велика літера "C" не відповідає стандартам HTML і просто не виглядає правильно.


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
Свиш

Ви не можете вбудовувати розриви рядків у літеральні рядки VB, навіть незважаючи на те, що ви можете бути дослідними рядками C #. Таким чином, вони не однакові.
Джої

@Svish, чекай, я щось пропускаю? Це зовсім не суперечка для VB. Дійсно, це одне місце, де VB виграє C #. Краще зробити це таким чином і чітко сформулювати нові рядки та спеціальні символи, а не кидати всі спеціальні символи між "і ".
Pacerier

@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 # підтримує дві форми рядкових літералів: звичайні рядкові літерали та дословні рядкові літерали.

Звичайний літеральний рядок складається з нуля або більше символів, укладених у подвійні лапки, як у "привіт", і може включати в себе як прості послідовності втечі (такі як \ t для символу вкладки), так і шістнадцяткову та послідовність втечі Unicode.

Дослівний рядковий літерал складається з символу @, який супроводжується символом подвійної цитати, нулем або більше символів та символом подвійної цитати, що закривається. Простий приклад - @ "привіт". У дослівному рядковому рядковому рядку символи між роздільниками інтерпретуються дослівно, єдиним винятком є ​​послідовність цитата-втечі. Зокрема, прості послідовності втечі та шістнадцяткові та послідовні відхилення Unicode не обробляються у дослівно-рядкових літералах. Дослівний рядковий літерал може охоплювати кілька рядків.


9

Це дословний рядок і змінює правила евакуації - єдиний символ, який тепер уникнути, - це ", втекли до" ". Це особливо корисно для шляхів до файлів і регулярних виразів:

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

тощо


Ви не пропускаєте @ у своєму прикладі, Марку? Або це за замовчуванням, коли я використовую var? Трохи розгублений ...
Дірк Волмар

1
Гаразд - це дійсно, дуже дивно. Цікаво, чи редактор їх манірував?
Марк Гравелл

9

Скопійовано з MSDN :

Під час компіляції дослівні рядки перетворюються на звичайні рядки з однаковими послідовностями втечі. Тому, якщо ви переглядаєте дослівну рядок у вікні перегляду відладчика, ви побачите символи втечі, які додав компілятор, а не дослівну версію зі свого вихідного коду. Наприклад, дослівна рядок @"C:\files.txt"з'явиться у вікні перегляду як "C:\\files.txt".


Що є типовим оманливим фрагментом документації Microsoft, IMHO! Що вищезазначене стверджує як кінцевий результат, є правильним, але основна істина полягає в тому, що рядки в C # перетворюються на відповідну послідовність байтів (або багатобайтові кодові символи). C # дозволяє двома різними способами представити нижню рядок, з @ "..." або "...". Налагоджувач завжди вибирає "..." шлях і не може в першу чергу визначити, який був використаний. (Послідовності втечі, такі як \ n або "", стосуються лише програмування та подання рядка на рівні дисплея, і ніколи не зберігаються в нижній рядку!)
MikeBeaton

8

Обрамлення @перед рядком дозволяє використовувати спеціальні символи , такі як косі або подвійні лапки , без необхідності використовувати спеціальні коди або керуючі символи.

Отже, ви можете написати:

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

замість:

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

3

Пояснення просте. Щоб представити рядок "string\", компілятор потребує, "string\\"оскільки \є символом втечі. Якщо ви використовуєте @"string\"замість цього, ви можете забути про це \\.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.