В чем смысл интерполяции строк?

На первый взгляд кажется, что он не делает ничего, кроме сохранения 2 символов для каждого встроенного выражения:

Console.WriteLine($"This is time number {i} that I, {name}, printed this statement.");
Console.WriteLine("This is time number "+i+" that I, "+name+", printed this statement.");

Это действительно стоит целой языковой функции?

При этом, должен признать, мне больше нравится смотреть на фигурные скобки, поэтому я использовал интерполяцию строк. Но почему он мне нравится больше? Какой психологический феномен предпочитает {hello} "+hello+"? Кажется немного произвольным.

Существуют ли другие преимущества интерполяции строк, которые оправдывают использование всей языковой функции? Или дело только в читабельности?

Когда интерполяция строк не эквивалентна простой текстовой замене "+ => { и +" => }?

Я знаю, что он компилируется в string.Format. Таким образом, результирующий двоичный файл отличается, но выполнение кажется таким же, плюс-минус некоторые очень незначительные различия в производительности.


person Nacht    schedule 17.09.2019    source источник
comment
В чем разница между "The number " + number.ToString() + " is greater than 0" и string.Format(Then number {0} is greater than 0", number)?   -  person Fabio    schedule 17.09.2019
comment
Что касается string.Format("{0} - {1}", a, b) по сравнению с $"{a} - {b}", он просто более удобочитаем/меньше подвержен риску человеческой ошибки при изменении.   -  person Llama    schedule 17.09.2019
comment
Я согласен, что это для удобочитаемости - в документации MS четко указано: если интерполированная строка имеет тип string, она обычно преобразуется в вызов метода String.Format. Компилятор может заменить String.Format на String.Concat, если анализируемое поведение будет эквивалентно конкатенации. - docs.microsoft.com/en-us/dotnet /csharp/языковая ссылка/   -  person Rob    schedule 17.09.2019
comment
@John, я собирался сказать, что другим замечательным вариантом использования является форматирование чисел, но я только что узнал, что интерполяция строк тоже может это делать. Не знал этого. Это может быть ответом на мой вопрос.   -  person Nacht    schedule 17.09.2019
comment
Это быстрее, чем конкатенация, и его легче читать, чем string.format. Быстрее и проще для чтения — хорошие аргументы в пользу языковой функции.   -  person Rufus L    schedule 17.09.2019


Ответы (3)


Я думаю, что ответ находится в официальных справочных документах на String Интерполяция:

Интерполяция строк обеспечивает более читаемый и удобный синтаксис для создания форматированных строк, чем составное форматирование строк.

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

var birthdate = new DateTime(1990,9,22);

Console.WriteLine($"Your birthday is {birthdate:MMMM dd}!");      // string interpolation

Console.WriteLine("Your birthday is {0:MMMM dd}!", birthdate);    // implicit String.Format

var message = "Your birthday is " +
                String.Format("{0:MMMM dd}", birthdate) + "!";    // explicit String.Format

Console.WriteLine(message);

// Your birthday is September 22!
person Grant Winney    schedule 17.09.2019
comment
Я принимаю этот ответ из-за ссылок и, в частности, вызываю функцию составного форматирования строк, чего мне не хватало. - person Nacht; 17.09.2019

Когда интерполяция строк не эквивалентна простой замене текста «+ => { и +» => }?

Все, что вы можете сделать с помощью интерполяции строк, в конечном итоге можно сделать с помощью конкатенации. Но интерполяция может быть быстрее написана, легче читаема и может (в некоторых случаях) выполняться быстрее во время выполнения.

Пример:

var a = 1.23456;
var b = 2.3434;
var check = false;

Console.WriteLine($"Hello {a/2:g7}, it looks like {b%1:g4} {(check ? "really" : "no")}"); // Fast to write, shorter, easier to read
Console.WriteLine("Hello {0:g7}, it looks like {1:g4} {2}", a /2, b % 1, check ? "really" : "no"); // Lack of compile time safety (may be wrong number of parameters)
Console.WriteLine("Hello " + (a/2).ToString("g7") + ", it looks like " + (b%1).ToString("g4") + " " + (check ? "really" : "no")); // Harder to read and write

Третий пример кода был особенно сложным с точки зрения правильности расстановки интервалов (например, пробела перед no). Использование интерполяции строк или string.Format (первая или вторая строки) в этом отношении намного проще.

Обратите внимание, что приведенный выше код на самом деле рисует лучшую картину для второго примера (с 0:g7), чем обычно, поскольку Console.WriteLine имеет встроенную логику string.Format (т. е. обычно вторая строка кода будет еще длиннее).

Интерполяция строк и ее поддержка FormattableString также открывают некоторые методы для генерации SQL, который не открывается для SQL-инъекций - но это, вероятно, выходит за рамки вашего вопроса.

person mjwills    schedule 17.09.2019

Я только что подумал о другом ответе на вопрос, почему {thing} намного читабельнее, чем "+thing+".

Конечно, есть основная причина, по которой мы, программисты, очень привыкли рассматривать фигурные скобки как группу. Однако есть особый случай, когда кавычки выглядят гораздо более нелепо, чем фигурные скобки.

Сравните следующее:

string s1 = "<div class=\"" + styling + "\">" + content + "</div>";
string s2 = "Field \"" + fieldname + "\" has been submitted with value \"" + fieldvalue + "\".";
string s3 = "select * from [" + dbname + "][" + schemaname + "][" + tablename + "] where " + fieldname + " = '" + escapedvalue + "'";
string s4 = "{\"jsonprop1\":{},\"jsonprop2\": \"" + value + "\"}";

к следующему:

string s1 = $"<div class=\"{styling}\">{content}</div>";
string s2 = $"Field \"{fieldname}\" has been submitted with value \"{fieldvalue}\".";
string s3 = $"select * from [{dbname}][{schemaname}][{tablename}] where " + fieldname + " = '{escapedvalue}'";
string s4 = $"{\"jsonprop1\":{},\"jsonprop2\": \"{value}\"}";

Обычно строки, в которые требуется вставить переменные, уже содержат кавычки или одинарные кавычки. Из-за этого еще больше цитат трудно разобрать глазами. Таким образом, просто иметь еще один вариант в качестве escape-символа — это хорошо.

person Nacht    schedule 29.10.2019