A constant used with string.Format would, by its nature, be intended to work with a specific number of arguments which each have a predetermined meaning.
In other words, if you create this constant:
const string FooFormat = "Foo named '{0}' was created on {1}.";
Then in order to use it you must have two arguments which are probably supposed to be a string and a DateTime.
So even before string interpolation we were in a sense using the constant as a function. In other words, instead of separating the constant, it might have made more sense to put it in a function instead, like this:
string FormatFooDescription(string fooName, DateTime createdDate) =>
string.Format("Foo named '{0}' was created on {1}.", fooName, createdDate);
It's still the same thing, except that the constant (string literal) is now located with the function and arguments that use it. They might as well be together, because the format string is useless for any other purpose. What's more, now you can see the intent of the arguments that are applied to the format string.
When we look at it that way, the similar use of string interpolation becomes obvious:
string FormatFooDescription(string fooName, DateTime createdDate) =>
$"Foo named '{fooName}' was created on {createdDate}.";
What if we have multiple format strings and we want to choose a particular one at runtime?
Instead of selecting which string to use, we could select a function:
delegate string FooDescriptionFunction(string fooName, DateTime createdDate);
Then we could declare implementations like this:
static FooDescriptionFunction FormatFoo { get; } = (fooName, createdDate) =>
$"Foo named '{fooName}' was created on {createdDate}.";
Or, better yet:
delegate string FooDescriptionFunction(Foo foo);
static FooDescriptionFunction FormatFoo { get; } = (foo) =>
$"Foo named '{foo.Name}' was created on {foo.CreatedDate}.";
}
string.Formatcalls.constwithstatic readonly