String Interpolation suggestion: Names in the FormattableString

Topics: C# Language Design
Jan 13, 2015 at 2:23 AM
Edited Jan 13, 2015 at 2:23 AM
As far as I understand, current proposed design for the FormattableString is:
public class FormattableString {
    public string Format { get; }
    public object[] Args { get; }
    // ...
I suggest a IReadOnlyList<string> Names { get; }.

This should be populated by the identifiers used to fill the 'holes' in the interpolated string, using to the same rules as the property names of the anonymous objects.

1. $"{x}, {y}"  // Names = "x", "y"
2. $"{x.Y.Z}"   // Names = "Z"
3. $"{x}, {5}"  // Names = "x", null
Since each call site has a fixed set of names, each list can be cached by the compiler and reused between calls. This means that even the names aren't used anywhere, the performance cost would be minimal.

That's the main reason why I suggest a second list instead of grouping names with values.

Use cases:
  1. Serilog framework, which currently has a custom string formatter. When the log entry is created from something like log.Information("Time elapsed: {elapsed}", elapsed) both the formatted string and the Name:Value pairs for each 'hole' are recoded.
  2. SQL generation -- having something like @name in the generated SQL would be much nicer than @p1.
  3. nameof shortcuts for argument checking. Example: Argument.NotNull(nameof(x), x) can be replaced with Argument.NotNull($"{x}") since arguments will always have inferable names.
Values with non-inferable names might be error-prone. Obviously libraries can fallback to x1, x2, etc for those, but there is no way for a library to ensure it requires a name.

I don't see it as a blocker though -- all use cases I thought about can handle it, and in argument validation you can't ensure that nameof is called with an argument anyway.
Jan 13, 2015 at 2:30 AM
Edited Jan 13, 2015 at 2:31 AM
We can always do this later. This release is pretty much in the bag and we don't have any runway for design changes.