Подтвердить что ты не робот

Линейный символ продолжения в С#

У нас есть unit test с переменной, которая содержит очень длинную строку.

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

В VB есть символ продолжения строки, есть ли equivilant в С#?

4b9b3361

Ответ 1

С# позволит вам иметь строку, разделенную на несколько строк, этот термин называется verbatim literal:

string myString = @"this is a
                    test
                   to see how long my string
                   can be



                    and it can be quite long";

Если вы ищете альтернативу & _ из VB, используйте + для соединения ваших строк.

Ответ 2

Строковые константы

Просто используйте оператор + и сломайте строку вверх в удобочитаемые строки. Компилятор подберет, что строки являются постоянными и объединяют их во время компиляции. См. Руководство по программированию MSDN С# здесь.

например.

const string myVeryLongString = 
    "This is the opening paragraph of my long string. " +
    "Which is split over multiple lines to improve code readability, " +
    "but is in fact, just one long string.";

IL_0003: ldstr "This is the opening paragraph of my long string. Which is split over multiple lines to improve code readability, but is in fact, just one long string."

Строковые переменные

Обратите внимание, что при использовании строковой интерполяции для подстановки значений в вашу строку символ $ должен предшествовать каждой строке, где должна выполняться подстановка:

var interpolatedString = 
    "This line has no substitutions. " +
    $" This line uses {count} widgets, and " +
    $" {CountFoos()} foos were found.";

Однако это имеет отрицательную производительность следствие множественных вызовов string.Format и возможной конкатенации строк (помеченных ***)

IL_002E:  ldstr       "This line has no substitutions. "
IL_0033:  ldstr       " This line uses {0} widgets, and "
IL_0038:  ldloc.0     // count
IL_0039:  box         System.Int32
IL_003E:  call        System.String.Format ***
IL_0043:  ldstr       " {0} foos were found."
IL_0048:  ldloc.1     // CountFoos
IL_0049:  callvirt    System.Func<System.Int32>.Invoke
IL_004E:  box         System.Int32
IL_0053:  call        System.String.Format ***
IL_0058:  call        System.String.Concat ***

Хотя вы можете использовать [email protected] для предоставления одной строки и избегать проблем с производительностью если пробел не помещается внутри {} (что выглядит странно, IMO), у этого есть такая же проблема, как и ответ Нила Найта, поскольку он будет включать любые пробелы в разбивке строк:

var interpolatedString = [email protected]"When breaking up strings with `@` it introduces
    <- [newLine and whitespace here!] each time I break the string.
    <- [More whitespace] {CountFoos()} foos were found.";

Введенные пробелы легко заметить:

IL_002E:  ldstr       "When breaking up strings with `@` it introduces
    <- [newLine and whitespace here!] each time I break the string.
    <- [More whitespace] {0} foos were found."

Альтернативой является возврат к string.Format. Здесь строка форматирования представляет собой единственную константу в соответствии с моим первоначальным ответом:

const string longFormatString = 
    "This is the opening paragraph of my long string with {0} chars. " +
    "Which is split over multiple lines to improve code readability, " +
    "but is in fact, just one long string with {1} widgets.";

И затем оценивается как таковой:

string.Format(longFormatString, longFormatString.Length, CountWidgets());

Однако это может быть сложным для поддержания, учитывая возможное разделение между строкой форматирования и токенами подстановки.

Ответ 4

Вы можете использовать дословные литералы:

const string test = @"Test
123
456
";

Но отступ 1-й строки сложный/уродливый.

Ответ 5

Вы должны использовать один из следующих способов:

    string s = @"loooooooooooooooooooooooong loooooong
                  long long long";

string s = "loooooooooong loooong" +
           " long long" ;

Ответ 6

В своем превосходном ответе StuartLC цитирует ответ на связанный вопрос и упоминает, что размещение новых строк внутри {expression} интерполированной строки "выглядит странно". Большинство согласится, но неприятный эффект исходного кода может быть несколько смягчен - и без каких-либо последствий во время выполнения - путем использования выделенных блоков {expression}, которые преобразуются в default(String), то есть null (и, в частности, не String.Empty).

(Хотя и второстепенный) смысл состоит в том, чтобы не испортить или не испортить ваш фактический контент выражения, вместо этого используя выделенный токен для этой цели. Так что, если вы объявите константу, например:

const String more = null;

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

var s1 = $"one: {99 + 1} two: {99 + 2} three: {99 + 3} four: {99 + 4} five: {99 + 5} six: {99 + 6}";

... вместо этого можно написать так.

var s2 = [email protected]"{more
    }one: {99 + 1} {more
    }two: {99 + 2} {more
    }three: {99 + 3} {more
    }four: {99 + 4} {more
    }five: {99 + 5} {more
    }six: {99 + 6}";

Или, возможно, вы предпочитаете другой "странный" подход к одной и той же вещи:

// elsewhere:
public const String Ξ = null;  // Unicode '\u039E', Greek 'Capital Letter Xi'

// anywhere:
var s3 = [email protected]"{
           Ξ}one: {99 + 1} {
           Ξ}two: {99 + 2} {
           Ξ}three: {99 + 3} {
           Ξ}four: {99 + 4} {
           Ξ}five: {99 + 5} {
           Ξ}six: {99 + 6}";

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

one: 100 two: 101 three: 102 four: 103 five: 104 six: 105

Как предположил Стюарт, производительность IL сохраняется в обоих этих примерах без использования + для конкатенации строк. Хотя более длинная строка формата в моем новом примере действительно хранится в IL, и, следовательно, в вашем исполняемом файле, пустые заполнители, на которые она ссылается, не инициализируются, и во время выполнения не возникает избыточных конкатенаций или вызовов функций. Для сравнения, вот IL для двух приведенных выше примеров.

IL для первого примера

ldstr "one: {0} two: {1} three: {2} four: {3} five: {4} six: {5}"
ldc.i4.6
newarr object
dup
ldc.i4.0
ldc.i4.s 100
box int32
stelem.ref
dup
ldc.i4.1
ldc.i4.s 101
box int32
stelem.ref
dup
ldc.i4.2
ldc.i4.s 102
box int32
stelem.ref
dup
ldc.i4.3
ldc.i4.s 103
box int32
stelem.ref
dup
ldc.i4.4
ldc.i4.s 104
box int32
stelem.ref
dup
ldc.i4.5
ldc.i4.s 105
box int32
stelem.ref
call string string::Format(string, object[])

IL для второго примера

ldstr "{0}one: {1} {2}two: {3} {4}three: {5} {6}four: {7} {8}five: {9} {10}six: {11}"
ldc.i4.s 12
newarr object
dup
ldc.i4.1
ldc.i4.s 100
box int32
stelem.ref
dup
ldc.i4.3
ldc.i4.s 101
box int32
stelem.ref
dup
ldc.i4.5
ldc.i4.s 102
box int32
stelem.ref
dup
ldc.i4.7
ldc.i4.s 103
box int32
stelem.ref
dup
ldc.i4.s 9
ldc.i4.s 104
box int32
stelem.ref
dup
ldc.i4.s 11
ldc.i4.s 105
box int32
stelem.ref
call string string::Format(string, object[])

Ответ 7

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

Int salary=2000;

String abc="I Love Pakistan";

Double pi=3.14;

Console.Writeline=salary+"/n"+abc+"/n"+pi;
Console.readkey();