Багаторядковий літеральний інтерпольований рядок C #


79

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);

Або:

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();

Або є щось більш елегантне?



@DmytroShevchenko, я справді розглядав можливість зробити це. Однак я не був впевнений у прийнятті вашої, коли спостерігав, як ви копіювали / вставляли найпопулярнішу відповідь за посиланням, розміщеним Ріком, а потім редагували її, щоб виглядати інакше. Це все сталося протягом 5 хвилин, тому редагування не видно. Ваша відповідь технічно правильна, але я відчував, що ви мали б надати належне. Я насправді хотів би прийняти коментар Ріка, але це неможливо.
Дрю Ноукс

@DrewNoakes ваше запитання позначено як копію запитання, на яке посилається Рік. Рік теж був тим, хто це позначив. Тож немає потреби додавати ще один екземпляр цього посилання до моєї відповіді. Якщо ви не згодні, я був би вдячний за ваші міркування. І звичайно, я відредагував код у своїй відповіді. Хоча, причина полягала не в тому, щоб виглядати по-іншому, а скоріше в тому, щоб відповідати прикладу у вашому запитанні.
Дмитро Шевченко

@DmytroShevchenko див. Нижній колонтитул сайту: внески користувачів, ліцензовані згідно cc by-sa 3.0 з необхідною атрибуцією
Drew Noakes

2
Голосування за відновлення. Передбачуване повторюване запитання задає щось інше і навпаки (вони хочуть розриви рядків у вихідному коді, але не рядок). Модератори, уважно читайте питання, перш ніж їх закривати!
Полковник Панік,

Відповіді:


152

Ви можете поєднати $і @разом, щоб отримати багаторядковий інтерпольований рядковий літерал:

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

Джерело: рядки інтерполяції довгих рядків у C # 6 (Дякую @Ric за пошук потоку!)


6
Я спробував це як @ $ (зворотне), і це не спрацювало, тому я зрозумів, що їх не можна поєднувати. Мені не спало на думку спробувати інший шлях.
kencordero

2
Починаючи з C # 8.0, ви можете використовувати маркери $ і @ у будь-якому порядку: і $ @ "...", і @ $ "..." є дійсними інтерпольованими дослівними рядками. У попередніх версіях C # маркер $ повинен з'являтися перед символом @.
Hal9000,

9

Я б, мабуть, використовував комбінацію

var builder = new StringBuilder()
    .AppendLine($"Width: {width}")
    .AppendLine($"Height: {height}")
    .AppendLine($"Background: {background}");

чи міг би голос за виборців дати якусь інформацію? Я не бачу жодних проблем із цим, чи є проблема?
сара

Для протоколу я насправді вас підтримав. Можуть бути випадки, коли це є більш читабельним. Єдиний негатив, який я можу придумати, - це те, що він створює кілька додаткових об’єктів для GC.
Дрю Ноукс

1
Я думаю, що це негатив лише у виняткових випадках, коли у вас дуже обмежені ресурси або вам потрібно додати тисячі, якщо не мільйони рядків. Я не особливо люблю дослівні рядки для форматування. Це робить макет тексту у файлі коду відповідальним за появу вихідних даних. Я віддаю перевагу конструктору струн, це виразніше.
сара

Я згоден з тим, що форматування дослівних рядків трохи потворне. String.Concatтут також може бути варіант.
Дрю Ноукс

Безумовно, як конкат більше, ніж дослівно. Найприємніше у stringbuilder - це те, що він дбає про те, щоб робити лінійні брейки за вас. Мені, мабуть, все в порядку.
sara

4

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

Наприклад

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

Я вважаю, що його легше форматувати та читати.

Це буде мати додаткові накладні витрати по порівнянні з використанням $ @ »" , але тільки в самих критичних до продуктивності додатків , це буде помітно. У пам'яті рядкові операції надзвичайно дешеві порівняно з даними вводу-виводу. Зчитування однієї змінної з db в більшості випадків триватиме в сотні разів довше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.