Есть ли простой способ создания многострочного литерала строки в С#?
Вот что у меня сейчас:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
Я знаю, что PHP имеет
<<<BLOCK
BLOCK;
Есть ли у С# что-то подобное?
Есть ли простой способ создания многострочного литерала строки в С#?
Вот что у меня сейчас:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
Я знаю, что PHP имеет
<<<BLOCK
BLOCK;
Есть ли у С# что-то подобное?
 Вы можете использовать символ @ перед string для формирования буквального строкового литерала:
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
Вам также не нужно экранировать специальные символы при использовании этого метода, за исключением двойных кавычек, как показано в ответе Джона Скита.
В С# он называется дословным строковым литералом, и нужно просто поставить @перед литералом. Это не только позволяет использовать несколько строк, но и отключает экранирование. Так, например, вы можете сделать:
string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
Единственное, что можно избежать - это то, что если вам нужна двойная кавычка, вам нужно добавить дополнительный символ двойной кавычки:
string quote = @"Jon said, ""This will work,"" - and it did!";
Еще один вопрос, на который нужно следить, это использование строковых литералов в 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)
Проблема с использованием строкового литерала, который я нахожу, заключается в том, что он может сделать ваш код немного "странным", потому что для того, чтобы не получить пробелы в самой строке, он должен быть полностью выровнен по левому краю:
    var someString = @"The
quick
brown
fox...";
Тьфу.
Итак, решение, которое мне нравится использовать, которое держит все в хорошем соответствии с остальной частью вашего кода:
var someString = String.Join(
    Environment.NewLine,
    "The",
    "quick",
    "brown",
    "fox...");
И, конечно, если вы просто хотите логически разделить строки оператора SQL, как и вы, и на самом деле не нуждаетесь в новой строке, вы всегда можете просто заменить Environment.NewLine на " ".
Как примечание, с С# 6.0 теперь вы можете комбинировать интерполированные строки со строковым литералом:
string camlCondition = [email protected]"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";
Почему люди продолжают путать строки со строковыми литералами? Принятый ответ - отличный ответ на другой вопрос; не к этому.
Я знаю, что это старая тема, но я пришел сюда, возможно, с тем же вопросом, что и ОП, и мне неприятно видеть, как люди продолжают неправильно его читать. Или, может быть, я неправильно понимаю, я не знаю.
Грубо говоря, строка - это область компьютерной памяти, которая во время выполнения программы содержит последовательность байтов, которые могут быть сопоставлены с текстовыми символами. Строковый литерал, с другой стороны, является частью исходного кода, еще не скомпилированного, который представляет значение, используемое для инициализации строки позже, во время выполнения программы, в которой она появляется.
В С# утверждение...
 string query = "SELECT foo, bar"
 + " FROM table"
 + " WHERE id = 42";
... не создает строку из трех строк, а содержит одну строку; конкатенация трех строк (каждая инициализируется из другого литерала), ни одна из которых не содержит модификатора новой строки.
Похоже, что ОП спрашивает -at меньше всего, что я хотел бы спросить у тех words-, не о том, как ввести в скомпилированную строку разрывы строк, которые имитируют найденные в исходном коде, а о том, как разбить для ясности длинная строка текста в исходном коде без разрывов в скомпилированной строке. И не требуя расширенного времени выполнения, потратил на объединение нескольких подстрок, исходящих из исходного кода. Как и обратные косые черты в многострочном строковом литерале в javascript или C++.
 Предложив использование стенографических строк, Nevermind StringBuilder s, String.Join или даже вложенные функции с строковыми разворотами, а что нет, заставляет меня думать, что люди на самом деле не понимание вопроса. Или, может быть, я не понимаю этого.
Насколько я знаю, С# не имеет (по крайней мере, в палеолитической версии, которую я все еще использую, из предыдущего десятилетия) функцию чистой генерации многострочных строковых литералов, которые могут быть разрешены во время компиляции, а не выполнения.
Возможно, текущие версии поддерживают это, но я подумал, что поделюсь разницей между строками и строковыми литералами.
ОБНОВИТЬ:
(Из комментария MeowCat2012) Вы можете. Подход "+" от OP - лучший. Согласно спецификации, оптимизация гарантирована: fooobar.com/questions/8229/...
Я не видел этого, поэтому я разместил его здесь (если вы заинтересованы в передаче строки, вы тоже можете это сделать.) Идея состоит в том, что вы можете разбить строку на несколько строк и добавить свои собственные (также на нескольких строках) любым способом. Здесь "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
                                )";
    }
Вы можете использовать @ и "".
        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";
Да, вы можете разбить строку на несколько строк, не вводя новые строки в фактическую строку, но это не очень красиво:
string s = [email protected]"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";
Хитрость заключается в том, чтобы ввести код, который оценивается как пустой, и этот код может содержать символы новой строки, не влияя на вывод. Я адаптировал этот подход из этого ответа к аналогичному вопросу.
По-видимому, существует некоторая путаница в отношении вопроса, но есть два намека на то, что нам нужен строковый литерал, не содержащий символов новой строки, определение которого состоит из нескольких строк. (в комментариях он так говорит, и "здесь, что у меня есть" показывает код, который не создает строку с символами новой строки в ней)
Этот unit тест показывает намерение:
    [TestMethod]
    public void StringLiteralDoesNotContainSpaces()
    {
        string query = "hi"
                     + "there";
        Assert.AreEqual("hithere", query);
    }
Измените приведенное выше определение запроса так, чтобы он представлял собой один строковый литерал вместо объединения двух строковых литералов, которые могут быть оптимизированы или не оптимизированы компилятором в один.
Подход C++ заключался бы в том, чтобы завершать каждую строку обратной косой чертой, в результате чего символ новой строки экранировался и не появлялся в выходных данных. К сожалению, все еще существует проблема, заключающаяся в том, что каждая строка после первой должна быть выровнена, чтобы не добавлять дополнительные пробелы к результату.
Есть только одна опция, которая не полагается на оптимизацию компилятора, которая может не произойти, - это поместить ваше определение в одну строку. Если вы хотите положиться на оптимизацию компилятора, то +, который у вас уже есть, великолепен; вам не нужно выравнивать строку по левому краю, вы не получаете новых строк в результате, и это всего лишь одна операция, без вызовов функций, чтобы ожидать оптимизации.
Если вам не нужны пробелы/новые строки, похоже, что сложение строк работает:
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.
Вы можете запустить выше здесь, если хотите.
Вы можете использовать эти два метода:
    private static String ReverseString(String str)
    {
        int word_length = 0;
        String result = "";
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == ' ')
            {
                result = " " + result;
                word_length = 0;
            }
            else
            {
                result = result.Insert(word_length, str[i].ToString());
                word_length++;
            }
        }
        return result;
    }
//NASSIM LOUCHANI
    public static string SplitLineToMultiline(string input, int rowLength)
    {
        StringBuilder result = new StringBuilder();
        StringBuilder line = new StringBuilder();
        Stack<string> stack = new Stack<string>(ReverseString(input).Split(' '));
        while (stack.Count > 0)
        {
            var word = stack.Pop();
            if (word.Length > rowLength)
            {
                string head = word.Substring(0, rowLength);
                string tail = word.Substring(rowLength);
                word = head;
                stack.Push(tail);
            }
            if (line.Length + word.Length > rowLength)
            {
                result.AppendLine(line.ToString());
                line.Clear();
            }
            line.Append(word + " ");
        }
        result.Append(line);
        return result.ToString();
    }
В SplitLineToMultiline() вам нужно определить строку, которую вы хотите использовать, и длину строки, это очень просто. Спасибо.