В чем разница между обычной строкой и дословной строкой?

166

У меня есть пробная версия Resharper, и она всегда предлагает переключать обычные строки в дословные. В чем разница?

Xaisoft
источник
3
Я никогда не видел это предложение от ReSharper. Можете ли вы привести пример, где это предполагает?
Джон Сондерс
3
Я только что получил это. Первым предложением было перенести его на ресурс, а вторым было сделать его дословной строкой: MessageBox.Show («Перед тем, как приступить к работе, нужно погладить утконоса»);
Б. Клэй Шеннон
Я все еще получаю это все время. Как правило, это одно из резких предупреждений, которые вы хотите отключить, поскольку оно предлагает дословно составлять строки без какой-либо причины.
Дин Свиатек
Если вам нравится моя предложенная функция для Visual Studio IDE, пожалуйста, оставьте отзыв здесь: developercommunity.visualstudio.com/idea/602807/…
Оливье Жако-

Ответы:

191

Строковая строка - это строка, которую не нужно экранировать, например имя файла:

string myFileName = "C:\\myfolder\\myfile.txt";

было бы

string myFileName = @"C:\myfolder\myfile.txt";

Символ @ означает буквальное прочтение этой строки, иначе не интерпретируйте управляющие символы.

alc6379
источник
12
Интересно, почему Решарпер предлагает это изменение? Знают ли какие-либо гуру CLR, более ли эффективно обрабатываются дословные строки, поскольку escape-символы можно игнорировать?
Мэтт Петерсон
9
Я думаю, что, возможно, ReSharper предлагает это, потому что дословная строка более читаема.
andyp
36
Я считаю, что это своего рода соглашение по кодированию (я никогда раньше не видел и не слышал). Для строк ReSharper предлагает либо переместить его в файл ресурсов для локализации, либо сделать его дословно - для дословных строк ReSharper больше не предлагает опцию локализации строки. Таким образом, похоже на соглашение, чтобы сделать все строки, которые не нуждаются в дословной локализации.
Даниэль Брюкнер
Допустим, у нас есть строковый литерал, назначенный строковой переменной, string myFileName = "C: \\ myfolder \\ myfile.txt"; Теперь я хочу преобразовать строковую переменную myFileName в дословную строку. Как мне это сделать? Это работает? строка verbatimStr = @myFileName;
sanjeev bhusal
3
@sanjeevbhusal: Вы действительно никогда не делаете это. @ "C: \ myfolder \ myfile.txt" и "C: \\ myfolder \\ myfile.txt" - это одно и то же для CLR. Это просто синтаксический сахар, в основном.
alc6379
68

Это описано в разделе 2.4.4.5 спецификации C # :

2.4.4.5 Строковые литералы

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

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

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

Другими словами, единственный специальный символ в @ "дословном строковом литерале" - это символ двойной кавычки. Если вы хотите написать дословную строку, содержащую двойные кавычки, вы должны написать две двойные кавычки. Все остальные символы интерпретируются буквально.

Вы можете даже иметь буквально новые строки в дословном строковом литерале. В обычном строковом литерале вы не можете иметь буквальные новые строки. Вместо этого вы должны использовать, например "\n".

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

Во время выполнения нет никакой разницы между строками, созданными из обычных строковых литералов, и строками, созданными из дословных строковых литералов - они оба имеют тип System.String.

Марк Байерс
источник
27

Между строкой и дословной строкой нет разницы во времени выполнения. Они отличаются только во время компиляции. Компилятор принимает меньше экранирующих последовательностей в дословной строке, так что что вы видите, то и получите, кроме экранирования кавычек.

Вы также можете использовать дословный символ @, чтобы сказать компилятору обрабатывать ключевое слово как имя:

var @if = "if";
//okay, treated as a name
Console.WriteLine(@if);
//compiler err, if without @ is a keyword
Console.WriteLine(if);

var @a = "a";
//okay
Console.WriteLine(@a);
//also okay, @ isn't part of the name
Console.WriteLine(a);
Корбин Март
источник
16

Вы также можете иметь многострочную строку, используя дословные строки:

Console.WriteLine(@"This
    is
    a
    Test
    for stackoverflow");

без @вас есть ошибка.

В VB14 появилась новая функция Multiline Strings, которая похожа на дословные строки в C #.

Многострочные строки

Совет от профессионала: строковые литералы VB теперь точно соответствуют дословным строкам C #.

Мохамад Ширализаде
источник
13

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

/*
This string contains a newline
and a tab    and an escaped backslash\
*/
Console.WriteLine("This string contains a newline\nand a tab\tand an escaped backslash\\");

Дословные строки интерпретируются как есть, без перевода каких-либо escape-последовательностей:

/* 
This string displays as is. No newlines\n, tabs\t or backslash-escapes\\.
*/
Console.WriteLine(@"This string displays as is. No newlines\n, tabs\t or backslash-escapes\\.");
BoltClock
источник
0

Если вы хотите удалить предупреждения Resharper, вы можете использовать:

Localizable(false)

Для таких вещей, как параметры, расположение файлов, например. это может быть хорошим решением.

AndyO
источник