Поделиться через


Разрешить новые строки во всех интерполяциях

Заметка

Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Это включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.

Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия отражены в соответствующей протоколе совещания по проектированию языка (LDM).

Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .

Сводка

Язык сегодня обрабатывает неглаговые и подробные интерполированные строки ($"" и $@"" соответственно) по-разному. Основной разумной разницы для них заключается в том, что интерполированная строка без детализации работает как обычная строка и не может содержать новые строки в его текстовых сегментах, и вместо этого следует использовать escape-запросы (например, \r\n). И наоборот, буквально интерполируемая строка может содержать новые строки в её текстовых сегментах (как в буквальной строке) и не экранирует новые строки или другие символы (за исключением "", чтобы экранировать саму кавычку).

Это все разумно и не изменится с этим предложением.

Сегодня кажется неразумным то, что мы расширяем ограничение на "нет новых линий" в недословной интерполируемой строке за пределы её текстовых сегментов и далее в сами интерполяции. Это означает, например, что вы не можете написать следующее:

var v = $"Count is\t: { this.Is.A.Really(long(expr))
                            .That.I.Should(
                                be + able)[
                                    to.Wrap()] }.";

В конечном счете, правило, что «интерполяция должна быть на одной строке», является лишь ограничением текущей реализации. Это ограничение действительно не нужно, может раздражать и его довольно просто убрать (см. задачу https://github.com/dotnet/roslyn/pull/54875, чтобы увидеть, как это сделать). В конце концов, все это заставляет разработчика размещать все в одной строке или использовать дословную интерполированную строку, что может быть неудобно.

Выражения интерполяции сами по себе не являются текстом и не должны подчиняться каким-либо правилам escape и перевода строки в них.

Изменение спецификации

single_regular_balanced_text_character
-    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B), } (U+007D) and new_line_character>'
-    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
+    : <Any character except @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B), } (U+007D)>
+    | comment
    ;

Обсуждения LDM

https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-09-20.md