Есть ли простой способ создать многострочный строковый литерал в C #?
Вот что у меня есть сейчас:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
Я знаю, что в PHP есть
<<<BLOCK
BLOCK;
Есть ли в C # что-то подобное?
Есть ли простой способ создать многострочный строковый литерал в C #?
Вот что у меня есть сейчас:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
Я знаю, что в PHP есть
<<<BLOCK
BLOCK;
Есть ли в C # что-то подобное?
Вы можете использовать символ @
перед string
, чтобы сформировать дословный строковый литерал:
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
Вам также не нужно экранировать специальные символы при использовании этого метод, за исключением двойных кавычек, как показано в ответе Джона Скита.
@"my string".Replace(Environment.NewLine, "")
- person John Rasch; 12.12.2012
@
фактически заставляет C # обрабатывать строковые литералы так же, как VB обрабатывает строковые литералы.
- person Achilles; 02.04.2015
@
и нового оператора C # $
?
- person Afshar Mohebi; 03.11.2015
Это называется буквальный строковый литерал. в C #, и нужно просто поставить @ перед литералом. Это не только позволяет использовать несколько строк, но также отключает экранирование. Так, например, вы можете:
string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
Однако это включает в себя разрывы строк (используя любой разрыв строки, который есть в вашем источнике) в строку. Для SQL это не только безвредно, но и, вероятно, улучшает читаемость везде, где вы видите строку, но в других местах это может не требоваться, и в этом случае вам либо нужно не использовать многострочную дословный строковый литерал, чтобы начать с него, или удалите его из результирующей строки.
Единственный недостаток экранирования заключается в том, что если вы хотите использовать двойные кавычки, вам нужно добавить дополнительный символ двойной кавычки:
string quote = @"Jon said, ""This will work,"" - and it did!";
Кстати, в C # 6.0 теперь вы можете комбинировать интерполированные строки с дословным строковым литералом:
string camlCondition = $@"
<Where>
<Contains>
<FieldRef Name='Resource'/>
<Value Type='Text'>{(string)parameter}</Value>
</Contains>
</Where>";
$@"{{example literal text { fooString }. }}"
Это может запутать некоторых, потому что Angular, React и Vue.js используют противоположное соглашение.
- person Patrick Szalapski; 21.05.2018
{date.ToString("yyyy-mm-dd")}
, вы можете рассмотреть ответ @dav_i, поскольку интерполяция более чистая, без необходимости возиться с двойными кавычками
- person AndrewGentry; 09.09.2020
Проблема с использованием строкового литерала, которую я обнаружил, заключается в том, что он может сделать ваш код немного "странным", потому что, чтобы не было пробелов в самой строке, она должна быть полностью выровнена по левому краю:
var someString = @"The
quick
brown
fox...";
Фу.
Итак, решение, которое мне нравится использовать, чтобы все было хорошо согласовано с остальной частью вашего кода:
var someString = String.Join(
Environment.NewLine,
"The",
"quick",
"brown",
"fox...");
И, конечно, если вы просто хотите логически разделить строки оператора SQL, как вы, и на самом деле не нуждаетесь в новой строке, вы всегда можете просто заменить Environment.NewLine
на " "
.
"The", "Quick", $"{fox.color}", "Fox"
- person AndrewGentry; 09.09.2020
Еще одна проблема, на которую следует обратить внимание, - это использование строковых литералов в 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)
Почему люди продолжают путать строки со строковыми литералами? Принятый ответ - отличный ответ на другой вопрос; не к этому.
Я знаю, что это старая тема, но я пришел сюда, возможно, с тем же вопросом, что и OP, и мне неприятно видеть, как люди продолжают неправильно ее читать. Или, может быть, я неправильно это читаю, не знаю.
Грубо говоря, строка - это область памяти компьютера, которая во время выполнения программы содержит последовательность байтов, которая может быть отображена в текстовые символы. С другой стороны, строковый литерал - это еще не скомпилированный фрагмент исходного кода, который представляет значение, используемое для инициализации строки позже, во время выполнения программы, в которой он появляется.
В C # инструкция ...
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
... создает не трехстрочную строку, а однострочную; объединение трех строк (каждая из которых инициализирована отдельным литералом), ни одна из которых не содержит модификатора новой строки.
Кажется, что OP, похоже, спрашивает - по крайней мере, то, что я хотел бы спросить с этими словами - это не то, как ввести в скомпилированную строку разрывы строк, которые имитируют те, которые находятся в исходном коде, а как разбить для ясности длинный , одна строка текста в исходном коде без введения разрывов в скомпилированной строке. И, не требуя увеличенного времени выполнения, тратится на объединение нескольких подстрок, поступающих из исходного кода. Как обратная косая черта в конце многострочного строкового литерала в javascript или C ++.
Предложение использовать дословные строки, не говоря уже о StringBuilder
s, String.Join
s или даже вложенных функциях с переворотами строк и т.д., заставляет меня думать, что люди действительно не понимают вопрос. А может я этого не понимаю.
Насколько мне известно, C # не имеет (по крайней мере, в палеолитической версии, которую я все еще использую, из предыдущего десятилетия), функции чистого создания многострочных строковых литералов, которые могут быть разрешены во время компиляции, а не исполнение.
Возможно, текущие версии поддерживают его, но я подумал, что поделюсь различием, которое я ощущаю между строками и строковыми литералами.
ОБНОВИТЬ:
(Из комментария MeowCat2012) Вы можете. Подход «+» OP является лучшим. Согласно спецификации оптимизация гарантирована: http://stackoverflow.com/a/288802/9399618
Добавьте несколько строк: используйте @
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
Добавьте строковые значения в середину: используйте $
string text ="beer";
string query = $"SELECT foo {text} bar ";
Многострочная строка Добавьте значения в середину: используйте $ @
string text ="Customer";
string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id = 42";
Вы можете использовать @ и "".
string sourse = @"{
""items"":[
{
""itemId"":0,
""name"":""item0""
},
{
""itemId"":1,
""name"":""item1""
}
]
}";
Я этого не видел, поэтому опубликую здесь (если вы заинтересованы в передаче строки, вы тоже можете это сделать). Идея состоит в том, что вы можете разбить строку на несколько строк и добавить свой собственный контент (также на нескольких строках) любым способом. Здесь "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
)";
}
createTable("MyTable");
. В любом случае вопрос OP заключался в том, как вводить многострочные строковые литералы непосредственно в код, а не как создавать запросы к базе данных как таковые. :)
- person dbeachy1; 28.02.2015
Да, вы можете разбить строку на несколько строк, не вводя символы новой строки в фактическую строку, но это не очень красиво:
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 ++ заключался бы в том, чтобы заканчивать каждую строку обратной косой чертой, в результате чего символ новой строки экранировался и не появлялся в выводе. К сожалению, все еще существует проблема, заключающаяся в том, что каждая строка после первой должна быть выровнена по левому краю, чтобы не добавлять дополнительные пробелы к результату.
Есть только один вариант, который не полагается на оптимизацию компилятора, которая может не произойти, - это поместить ваше определение в одну строку. Если вы хотите положиться на оптимизацию компилятора, то уже имеющийся у вас + отлично; вам не нужно выравнивать строку по левому краю, в результате вы не получаете символы новой строки, и только одна операция, без вызовов функций, ожидает оптимизации.
Если вам не нужны пробелы / новые строки, кажется, что добавление строк работает:
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.
При желании вы можете выполнить указанное выше здесь.
42
в качестве параметра, особенно если он поступает от пользователя, чтобы избежать SQL-инъекции. - person Jens Mühlenhoff   schedule 24.10.2013