Улучшения Интерполяции Строк в C# 10
Продолжаем знакомиться с новинками в новой версии C#.
Интерполированные обработчики строк
Как известно, компилятор превращает интерполированные строки в вызов
string.Format. Это может привести к большому количеству аллокаций: упаковке аргументов, выделению массива аргументов и, конечно же, самой результирующей строки. Кроме того, он не оставляет места для манёвра в смысле самой интерполяции.В C# 10 добавили библиотечный шаблон, который позволяет API «брать на себя» обработку аргумента в виде интерполированной строки. Когда используется интерполированная строка, компилятор проверяет, назначена ли интерполированная строка типу, который удовлетворяет шаблону обработчика интерполированной строки. Обработчик интерполированной строки - это особый тип, который преобразует интерполированную строку в обычную строку. Он применяется в специализированных сценариях обычно по соображениям производительности.
Для примера рассмотрим
StringBuilder.Append:var sb = new StringBuilder();До сих пор это вызывало перегрузку
sb.Append($"Привет, {args[0]}, как дела?");
Append(string? value), передавая туда аллоцированную и вычисленную строку, и добавляло её к StringBuilder одним блоком. Однако теперь есть новая перегрузка Append(ref StringBuilder.AppendInterpolatedStringHandler handler), которая имеет приоритет над предыдущей, когда в качестве аргумента используется интерполированная строка.Авторы API проделали некоторую работу «под капотом» и добавили перегрузки с параметрами вида
[Something]InterpolatedStringHandler, чтобы обрабатывать интерполированные строки более подходящим образом для своих целей. В нашем примере с добавлением строки " Привет, ", args[0] и ", как дела?" будут по отдельности добавлены к StringBuilder, что намного эффективнее, хотя имеет тот же результат.Иногда вы хотите выполнить работу по построению строки только при определенных условиях. Примером является
Debug.Assert:Debug.Assert(condition, $"{КакойТоСложныйМетод()}");
В большинстве случаев condition будет true, и второй параметр не будет использоваться. Однако все аргументы вычисляются при каждом вызове, излишне замедляя выполнение. Debug.Assert теперь имеет перегрузку с обработчиком интерполированных строк, который гарантирует, что второй аргумент даже не вычисляется, если условие истинно.Наконец, вот пример фактического изменения поведения строковой интерполяции.
String.Create() позволяет вам указать IFormatProvider, используемый для форматирования заменяемых выражений:String.Create(CultureInfo.InvariantCulture, $"Ответ: {result}");
Значение result (число или дата) будет отформатировано в соответствии с переданной культурой.Константные интерполированные строки
Если все замены в интерполированной строке являются константными строками, тогда результирующая строка также будет константой. Это позволяет использовать синтаксис интерполяции строк в большем количестве мест, например в атрибутах:
[Obsolete($"Используйте {nameof(OtherMethod)}")]
Обратите внимание, что замещаемые элементы должны быть заполнены константными строками. Другие типы, такие как числовые значения или значения даты, использовать нельзя, поскольку они чувствительны к культуре и не могут быть вычислены во время компиляции.Источник: https://devblogs.microsoft.com/dotnet/welcome-to-csharp-10/