Многострочный интерполированный строковый литерал C#

C# 6 предоставляет компилятору поддержку интерполированных строковых литералов с синтаксисом:

var person = new { Name = "Bob" };

string s = $"Hello, {person.Name}.";

Это отлично подходит для коротких строк, но если вы хотите создать более длинную строку, нужно ли указывать ее в одной строке?

С другими типами строк вы можете:

    var multi1 = string.Format(@"Height: {0}
Width: {1}
Background: {2}",
        height,
        width,
        background);

Or:

var multi2 = string.Format(
    "Height: {1}{0}" +
    "Width: {2}{0}" +
    "Background: {3}",
    Environment.NewLine,
    height,
    width,
    background);

Я не могу найти способ добиться этого с помощью интерполяции строк, не имея всего одной строки:

var multi3 = $"Height: {height}{Environment.NewLine}Width: {width}{Environment.NewLine}Background: {background}";

Я понимаю, что в этом случае вы можете использовать \r\n вместо Environment.NewLine (менее переносимый) или вытащить его на локальный, но будут случаи, когда вы не сможете уменьшить его ниже одной строки без потери семантической силы.

Просто интерполяция строк не должна использоваться для длинных строк?

Должны ли мы просто использовать StringBuilder для более длинных строк?

var multi4 = new StringBuilder()
    .AppendFormat("Width: {0}", width).AppendLine()
    .AppendFormat("Height: {0}", height).AppendLine()
    .AppendFormat("Background: {0}", background).AppendLine()
    .ToString();

Или есть что-то более изящное?


person Drew Noakes    schedule 20.10.2015    source источник
comment
@DmytroShevchenko, я думал об этом. Однако я не был уверен, что приму ваш, поскольку наблюдал, как вы копируете/вставляете ответ с наибольшим количеством голосов из ссылки, которую разместил Рик. , затем отредактируйте его, чтобы он выглядел иначе. Это все произошло в течение 5 минут, поэтому правки не видны. Ваш ответ технически правильный, но я чувствовал, что вы должны были отдать должное. На самом деле я хотел бы принять комментарий Рика, но это невозможно.   -  person Drew Noakes    schedule 21.10.2015
comment
@DrewNoakes ваш вопрос был помечен как дубликат вопроса, на который ссылается Рик. Рик тоже отметил это. Так что нет необходимости добавлять еще один экземпляр этой ссылки в мой ответ. Если вы не согласны, буду признателен за ваши аргументы. И, конечно же, я отредактировал код в своем ответе. Хотя причина была не в том, чтобы он выглядел иначе, а в том, чтобы соответствовать примеру в вашем вопросе.   -  person Dmytro Shevchenko    schedule 21.10.2015
comment
@DmytroShevchenko см. нижний колонтитул сайта: материалы пользователей под лицензией cc by-sa 3.0 с указанием авторства   -  person Drew Noakes    schedule 21.10.2015
comment
@DrewNoakes Ха! Это хороший аргумент! :) Отредактировал мой ответ.   -  person Dmytro Shevchenko    schedule 21.10.2015
comment
Голосование за открытие. Предполагаемый повторяющийся вопрос задает что-то другое и противоположное (они хотят разрывов строк в исходном коде, но не строки). Модераторы, внимательно читайте вопросы, прежде чем закрывать их!   -  person Colonel Panic    schedule 05.05.2016


Ответы (3)


Вы можете объединить $ и @ вместе, чтобы получить многострочный интерполированный строковый литерал:

string s =
$@"Height: {height}
Width: {width}
Background: {background}";

Источник: Длинные строки интерполяции строк в C#6 (спасибо @Ric за поиск темы!)

person Dmytro Shevchenko    schedule 20.10.2015
comment
Я пробовал это как @$ (обратное), и это не сработало, поэтому я решил, что их нельзя комбинировать. Мне не приходило в голову попробовать по-другому. - person kencordero; 15.02.2017
comment
Начиная с C# 8.0, вы можете использовать токены $ и @ в любом порядке: и $@..., и @$... являются допустимыми интерполированными дословными строками. В более ранних версиях C# маркер $ должен стоять перед маркером @. - person hal9000; 24.03.2020

Я бы, вероятно, использовал комбинацию

var builder = new StringBuilder()
    .AppendLine($"Width: {width}")
    .AppendLine($"Height: {height}")
    .AppendLine($"Background: {background}");
person sara    schedule 20.10.2015
comment
может ли downvoter дать какие-либо идеи? Я не вижу никаких проблем с этим, есть ли проблема? - person sara; 20.10.2015
comment
Для справки, я на самом деле проголосовал за вас. Могут быть случаи, когда это более читабельно. Единственный минус, о котором я могу думать, это то, что он создает несколько дополнительных объектов для GC. - person Drew Noakes; 21.10.2015
comment
Я думаю, что это только минус в исключительных случаях, когда у вас очень ограниченные ресурсы или вам нужно добавить тысячи, если не миллионы строк. Мне не особенно нравятся дословные строки для форматирования. Это делает расположение текста в файле кода ответственным за внешний вид вывода. Я предпочитаю stringbuilder, он более выразительный. - person sara; 21.10.2015
comment
Я согласен с тем, что форматирование дословных строк немного уродливо. String.Concat также может быть вариантом здесь. - person Drew Noakes; 22.10.2015
comment
Определенно нравится concat больше, чем дословно. Преимущество stringbuilder заключается в том, что он заботится о разрывах строк за вас. Хотя, наверное, я был бы в порядке с любым из них. - person sara; 22.10.2015
comment
@sara Я думаю, что ваш комментарий об использовании дословных строк для форматирования делает макет текста в файле кода ответственным за внешний вид вывода. это действительно отличный момент! Это заставило меня переосмыслить мой подход к форматированию многострочной строки. Я думаю, может быть, если бы вы включили это утверждение в свой ответ, это могло бы заставить проголосовавших задуматься, почему они на самом деле голосовали против, а не просто не любили ответ или думали, что он не отвечает на конкретный вопрос ОП (что он и сделал) вместо того, чтобы отвечать на вопрос && подчеркивая качество кода. - person Adam Porad; 09.10.2019
comment
они могли бы понизить это, поскольку оно не создает форматируемую строку, например, ее нельзя использовать в ExecuteSqlInterpolated - person Patrick Beynio; 02.12.2020
comment
Производительность интерполированных строк кажется очень хорошей, намного лучше, чем у StringBuilder. - person cskwg; 12.03.2021

Лично я просто добавляю еще одну интерполированную строку, используя конкатенацию строк

Например

var multi  = $"Height     : {height}{Environment.NewLine}" +
             $"Width      : {width}{Environment.NewLine}" +
             $"Background : {background}";

Я считаю, что это легче форматировать и читать.

Это будет иметь дополнительные накладные расходы по сравнению с использованием $@" ", но это будет заметно только в наиболее критичных к производительности приложениях. Операции со строками в памяти чрезвычайно дешевы по сравнению с вводом-выводом данных. Чтение одной переменной из базы данных в большинстве случаев займет в сотни раз больше времени.

person Andrew Monteith    schedule 15.02.2017