簡體   English   中英

如何編譯C#字符串插值?

[英]How is C# string interpolation compiled?

我知道插值是string.Format()語法糖,但是當它與字符串格式化方法一起使用時,它是否有任何特殊的行為/識別?

如果我有一個方法:

void Print(string format, params object[] parameters)

以下使用插值調用它:

Print($"{foo} {bar}");

以下哪個調用行最相當於字符串插值的編譯結果?

Print(string.Format("{0} {1}", new[] { foo, bar }));
Print("{0} {1}", new[] { foo, bar });

問題背后的推理:諸如NLog之類的記錄框架通常會推遲字符串格式化,直到確定將實際寫入日志消息為止。 一般來說,我更喜歡字符串插值語法,但我需要知道它是否會產生額外的性能損失。

它以兩種方式之一編譯。

如果使用字符串插值表達式,其中需要一個string ,則將其編譯為對string.Format的調用。

基本上,這個:

string s = $"now is {DateTime.Now}";

變成了這個:

string s = string.Format("now is {0}", DateTime.Now);

在Try Roslyn中親眼看看

這里沒什么神奇的。

現在,另一方面,如果您在一個需要FormattableString (.NET 4.6中的新類型)的地方使用它,它將被編譯為對FormattableStringFactory.Create的調用:

public void Test(FormattableString s)
{
}

Test($"now is {DateTime.Now}");

那里的電話變成了這樣:

Test(FormattableStringFactory.Create("now is {0}", DateTime.Now));

在Try Roslyn中親眼看看

所以從本質上講,回答你的最后一個問題:

這個電話:

Print($"{foo} {bar}");

將翻譯成這個:

Print(string.Format("{0} {1}", foo, bar));

這甚至會在調用Print之前通過string.Format產生格式化成本。

如果您可以添加或找到帶有FormattableStringPrint FormattableString ,那么您可以推遲string.Format的實際成本,直到您確定是否需要記錄為止。 這在運行時是否具有可測量的差異很難說。

在Try Roslyn中親眼看看


獎金回合

不僅延遲了實際格式,而且FormattableStringToString方法允許您指定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")));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM