У нас есть unit test с переменной, которая содержит очень длинную строку.
Вопрос заключается в том, как записать это в код, без проблем с разрывами строк или что код трудно читать.
В VB есть символ продолжения строки, есть ли equivilant в С#?
У нас есть unit test с переменной, которая содержит очень длинную строку.
Вопрос заключается в том, как записать это в код, без проблем с разрывами строк или что код трудно читать.
В VB есть символ продолжения строки, есть ли equivilant в С#?
С# позволит вам иметь строку, разделенную на несколько строк, этот термин называется verbatim literal
:
string myString = @"this is a
test
to see how long my string
can be
and it can be quite long";
Если вы ищете альтернативу & _
из VB, используйте +
для соединения ваших строк.
Строковые константы
Просто используйте оператор +
и сломайте строку вверх в удобочитаемые строки. Компилятор подберет, что строки являются постоянными и объединяют их во время компиляции. См. Руководство по программированию 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());
Однако это может быть сложным для поддержания, учитывая возможное разделение между строкой форматирования и токенами подстановки.
@"string here
that is long you mean"
Но будьте осторожны, потому что
@"string here
and space before this text
means the space is also a part of the string"
Он также избегает вещей в строке
@"c:\\folder" // c:\\folder
@"c:\folder" // c:\folder
"c:\\folder" // c:\folder
Похожие
Вы можете использовать дословные литералы:
const string test = @"Test
123
456
";
Но отступ 1-й строки сложный/уродливый.
Вы должны использовать один из следующих способов:
string s = @"loooooooooooooooooooooooong loooooong
long long long";
string s = "loooooooooong loooong" +
" long long" ;
В своем превосходном ответе 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[])
Если вы указали разные переменные, используйте следующий простой метод:
Int salary=2000;
String abc="I Love Pakistan";
Double pi=3.14;
Console.Writeline=salary+"/n"+abc+"/n"+pi;
Console.readkey();