I know that interpolation is syntactic sugar for string.Format()
, but does it have any special behavior/recognition of when it is being used with a string formatting method?
If I have a method:
void Print(string format, params object[] parameters)
And the following call to it using interpolation:
Print($"{foo} {bar}");
Which of the following calls lines is most equivalent to the compiled result of string interpolation?
Print(string.Format("{0} {1}", new[] { foo, bar }));
Print("{0} {1}", new[] { foo, bar });
Reasoning behind the question: Logging frameworks such as NLog typically defer string formatting until they have determined that a log message will actually be written. In general I prefer the string interpolation syntax, but I need to know if it may incur an extra performance penalty.
It is compiled in one of two ways.
If you use a string interpolation expression where a string
is expected, it is compiled into a call to string.Format
.
Basically, this:
string s = $"now is {DateTime.Now}";
is turned into this:
string s = string.Format("now is {0}", DateTime.Now);
See it for yourself in Try Roslyn .
Nothing magical here.
Now, on the other hand, if you use it in a place where a FormattableString
(a new type in .NET 4.6) is expected, it is compiled into a call to FormattableStringFactory.Create
:
public void Test(FormattableString s)
{
}
Test($"now is {DateTime.Now}");
The call there is turned into this:
Test(FormattableStringFactory.Create("now is {0}", DateTime.Now));
See it for yourself in Try Roslyn .
So in essence, to answer your final question there:
This call:
Print($"{foo} {bar}");
Will be translated to this:
Print(string.Format("{0} {1}", foo, bar));
which will incur the cost of the formatting through string.Format
before Print
is even called.
If you could add, or find, an overload of Print
that takes a FormattableString
, then you could defer the actual cost of string.Format
until after you've figured out if you need to log. Whether this has a measurable different in runtime is hard to say.
See it for yourself in Try Roslyn .
Not only is the actual formatting deferred, but the ToString
method of FormattableString
allows you to specify a IFormatProvider
.
This means that you can defer localized transformation as well.
public static void Print(FormattableString s)
{
Console.WriteLine("norwegian: " + s.ToString(CultureInfo.GetCultureInfo("nb-NO")));
Console.WriteLine("us: " + s.ToString(CultureInfo.GetCultureInfo("en-US")));
Console.WriteLine("swedish: " + s.ToString(CultureInfo.GetCultureInfo("sv-SE")));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.