Многострочный строковый литерал в C # - PullRequest
891 голосов
/ 09 июля 2009

Есть ли простой способ создать многострочный строковый литерал в C #?

Вот что у меня сейчас:

string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";

Я знаю, что PHP имеет

<<<BLOCK

BLOCK;

Есть ли в C # нечто похожее?

Ответы [ 11 ]

1377 голосов
/ 09 июля 2009

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

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

Вы также не должны экранировать специальные символы при использовании этого метода, за исключением двойных кавычек, как показано в ответе Джона Скита.

503 голосов
/ 09 июля 2009

Он называется дословным строковым литералом в C #, и просто нужно поставить @ перед литералом. Это не только позволяет использовать несколько строк, но и отключает экранирование. Так, например, вы можете сделать:

string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";

Единственное, что можно избежать - это то, что если вам нужна двойная кавычка, вам нужно добавить дополнительный символ двойной кавычки:

string quote = @"Jon said, ""This will work,"" - and it did!";
98 голосов
/ 24 сентября 2009

Еще один момент, за которым нужно следить - это использование строковых литералов в string.Format. В этом случае вам нужно избегать фигурных скобок / скобок '{' и '}'.

// this would give a format exception
string.Format(@"<script> function test(x) 
      { return x * {0} } </script>", aMagicValue)
// this contrived example would work
string.Format(@"<script> function test(x) 
      {{ return x * {0} }} </script>", aMagicValue)
91 голосов
/ 07 августа 2014

Проблема с использованием строкового литерала, который я обнаружил, состоит в том, что он может сделать ваш код немного « странным », потому что для того, чтобы не получить пробелы в самой строке, он должен быть полностью выровнен по левому краю:

    var someString = @"The
quick
brown
fox...";

Тьфу.

Таким образом, решение, которое мне нравится использовать, которое сохраняет все хорошо согласованным с остальным вашим кодом:

var someString = String.Join(
    Environment.NewLine,
    "The",
    "quick",
    "brown",
    "fox...");

И, конечно, если вы просто хотите логически разделить строки SQL-оператора, как вы, и вам не нужна новая строка, вы всегда можете просто заменить Environment.NewLine на " ".

84 голосов
/ 13 августа 2015

Как примечание: теперь в C # 6.0 вы можете комбинировать интерполированные строки с буквальным строковым литералом:

string camlCondition = $@"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";
38 голосов
/ 17 июля 2016

Почему люди продолжают путать строки со строковыми литералами? Принятый ответ - отличный ответ на другой вопрос; не к этому.

Я знаю, что это старая тема, но я пришел сюда, возможно, с тем же вопросом, что и ОП, и мне неприятно видеть, как люди продолжают неправильно его читать. Или, может быть, я неправильно понимаю, я не знаю.

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

В C # утверждение ...

 string query = "SELECT foo, bar"
 + " FROM table"
 + " WHERE id = 42";

... не создает строку из трех строк, а одну строку; конкатенация трех строк (каждая инициализируется из другого литерала), ни одна из которых не содержит модификатора новой строки.

То, что ОП спрашивает - по крайней мере, то, что я хотел бы спросить с этими словами, - это не то, как ввести в скомпилированную строку разрывы строк, которые имитируют найденные в исходном коде, а как разбить на Ясность длинной, единственной строки текста в исходном коде без , вводящей разрывы в скомпилированной строке. И не требуя расширенного времени выполнения, потратил на объединение нескольких подстрок, исходящих из исходного кода. Как и обратные косые черты внутри многострочного строкового литерала в javascript или C ++.

Предложение использовать дословные строки, не говоря уже о StringBuilder s, String.Join s или даже вложенных функциях с обращением строк и что нет, заставляет меня думать, что люди не совсем понимают вопрос. А может я этого не понимаю.

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

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

11 голосов
/ 19 сентября 2014

Я не видел этого, поэтому я опубликую это здесь (если вы заинтересованы в передаче строки, вы также можете сделать это.) Идея состоит в том, что вы можете разбить строку на несколько строк и добавить свою собственную содержание (также в несколько строк) любым способом, который вы хотите. Здесь «tableName» может быть передано в строку.

    private string createTableQuery = "";

    void createTable(string tableName)
    {

         createTableQuery = @"CREATE TABLE IF NOT EXISTS
                ["+ tableName  + @"] (
               [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
               [Key] NVARCHAR(2048)  NULL, 
               [Value] VARCHAR(2048)  NULL
                                )";
    }
4 голосов
/ 06 июня 2018

Вы можете использовать @ и "" .

        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";
2 голосов
/ 21 декабря 2018

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

string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";

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

По-видимому, существует некоторая путаница относительно вопроса, но есть два намека на то, что нам нужен строковый литерал, не содержащий символов новой строки, определение которого охватывает несколько строк. (в комментариях он так говорит, и «вот что у меня есть» показывает код, который не создает строку с символами новой строки в ней)

Этот модульный тест показывает намерение:

    [TestMethod]
    public void StringLiteralDoesNotContainSpaces()
    {
        string query = "hi"
                     + "there";
        Assert.AreEqual("hithere", query);
    }

Измените приведенное выше определение запроса так, чтобы он представлял собой один строковый литерал вместо объединения двух строковых литералов, которые могут быть оптимизированы или не оптимизированы одним компилятором.

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

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

1 голос
/ 13 мая 2015

Если вы не хотите использовать пробелы / переводы строк, добавление строк работает:

var myString = String.Format(
  "hello " + 
  "world" +
  " i am {0}" +
  " and I like {1}.",
  animalType,
  animalPreferenceType
);
// hello world i am a pony and I like other ponies.

Вы можете запустить выше здесь , если хотите.

...