[英]How is C# string interpolation compiled?
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? 我知道插值是
string.Format()
语法糖,但是当它与字符串格式化方法一起使用时,它是否有任何特殊的行为/识别?
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. 问题背后的推理:诸如NLog之类的记录框架通常会推迟字符串格式化,直到确定将实际写入日志消息为止。 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
. 如果使用字符串插值表达式,其中需要一个
string
,则将其编译为对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 . 在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
: 现在,另一方面,如果您在一个需要
FormattableString
(.NET 4.6中的新类型)的地方使用它,它将被编译为对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 . 在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. 这甚至会在调用
Print
之前通过string.Format
产生格式化成本。
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. 如果您可以添加或找到带有
FormattableString
的Print
FormattableString
,那么您可以推迟string.Format
的实际成本,直到您确定是否需要记录为止。 Whether this has a measurable different in runtime is hard to say. 这在运行时是否具有可测量的差异很难说。
See it for yourself in Try Roslyn . 在Try Roslyn中亲眼看看 。
Not only is the actual formatting deferred, but the ToString
method of FormattableString
allows you to specify a IFormatProvider
. 不仅延迟了实际格式,而且
FormattableString
的ToString
方法允许您指定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")));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.