Two new features are introduced in C# 10.0 to improve interpolated strings C# 6.0: the interpolated string handler pattern, marked with the [InterpolatedStringHandler] attribute, and the DefaultInterpolatedStringHandler struct in .NET 6. Together these provide for improved default performance as well as the ability to create custom interpolated string handlers.
In prior versions of .NET most string interpolation expressions used String.Format which is inefficient due to its flexibility, as well as boxing of value types and the creation of intermediate strings. This was especially problematic when used in loops or other performance-critical code and inefficient with logging where the log message is often discarded after all overhead is incurred.
By default the compiler now builds interpolated strings with DefaultInterpolatedStringHandler, which appends each part to a pooled buffer much like StringBuilder, avoiding boxing and intermediate strings. A method can also receive the interpolated string directly by taking a parameter whose type is marked with [InterpolatedStringHandler]; the compiler then fills in that handler instead of creating a string.
Additionally developers can create their own handlers to perform operations such as encoding values or skipping formatting entirely when the string is not needed.
Code
// StringBuilder.Append has a handler overload, so each part is
// appended straight into the builder with no intermediate string
builder.Append($"Order {orderId} has a total of {total:C}");// Interpolating would allocate a temporary string first,
// so hot paths appended each part separately
builder.Append("Order ").Append(orderId)
.Append(" has a total of ").Append(total.ToString("C"));Notes
- Handlers can also skip formatting altogether, which is how
Debug.Assert(condition, $"...")avoids building its message when the condition is true ILogger.LogInformationand the otherMicrosoft.Extensions.Loggingextension methods do not use a handler, so an interpolated string passed to them is still formatted even when the log level is disabled