Mer*_*rad 21 c# string-formatting roslyn c#-6.0
我知道插值是语法糖string.Format(),但它是否有任何特殊的行为/识别何时与字符串格式化方法一起使用?
如果我有一个方法:
void Print(string format, params object[] parameters)
Run Code Online (Sandbox Code Playgroud)
以下使用插值调用它:
Print($"{foo} {bar}");
Run Code Online (Sandbox Code Playgroud)
以下哪个调用行最相当于字符串插值的编译结果?
Print(string.Format("{0} {1}", new[] { foo, bar }));
Print("{0} {1}", new[] { foo, bar });
Run Code Online (Sandbox Code Playgroud)
问题背后的推理:诸如NLog之类的记录框架通常会推迟字符串格式化,直到确定将实际写入日志消息为止.一般来说,我更喜欢字符串插值语法,但我需要知道它是否会产生额外的性能损失.
ang*_*son 29
它以两种方式之一编译.
如果你使用字符串插值表达式,其中a string是预期的,它被编译成一个调用string.Format.
基本上,这个:
string s = $"now is {DateTime.Now}";
Run Code Online (Sandbox Code Playgroud)
变成了这个:
string s = string.Format("now is {0}", DateTime.Now);
Run Code Online (Sandbox Code Playgroud)
这里没什么神奇的.
现在,另一方面,如果您在一个需要FormattableString(.NET 4.6中的新类型)的地方使用它,它将编译成一个调用FormattableStringFactory.Create:
public void Test(FormattableString s)
{
}
Test($"now is {DateTime.Now}");
Run Code Online (Sandbox Code Playgroud)
那里的电话变成了这样:
Test(FormattableStringFactory.Create("now is {0}", DateTime.Now));
Run Code Online (Sandbox Code Playgroud)
所以从本质上讲,回答你的最后一个问题:
这个电话:
Print($"{foo} {bar}");
Run Code Online (Sandbox Code Playgroud)
将翻译成这个:
Print(string.Format("{0} {1}", foo, bar));
Run Code Online (Sandbox Code Playgroud)
甚至可以调用string.Format以前的格式化成本Print.
如果您可以添加或找到Print需要a 的重载FormattableString,那么您可以推迟实际成本,string.Format直到您确定是否需要记录为止.这在运行时是否具有可测量的差异很难说.
不仅推迟了实际的格式,但ToString方法FormattableString可以让你指定一个IFormatProvider.
这意味着您也可以推迟本地化转换.
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")));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1821 次 |
| 最近记录: |