【问题标题】:Does C# 6.0's String interpolation rely on Reflection?C# 6.0 的字符串插值是否依赖反射?
【发布时间】:2015-07-11 16:35:10
【问题描述】:

简短而简单。 C# 6.0 中的新字符串插值是否依赖反射? IE。会

string myStr = $"Hi {name}, how are you?";

在运行时使用反射来查找变量“name”及其值?

【问题讨论】:

  • 为什么需要?编译器拥有它需要的所有信息。如果变量名name在作用域内,就会被使用,否则会报错。
  • 我不知道,这就是我问的原因。我不确定格式字符串是否“按原样”保存在二进制文件中,然后会填充空白(在经典情况下 {0} 等带有变量)。如果是这样的话,那就得使用反射了,但我不知道编译器是如何处理这些语句的
  • 我不知道,但我肯定会偷看诸如 dotPeek 之类的反编译器,看看发生了什么
  • 你可以推理出来,反射无法在字符串文字上检测到$。只有编译器可以看到它。它告诉它解析字符串,在字符串中查找{identifier} 并生成适当的 String.Format() 语句。

标签: c# string-interpolation c#-6.0


【解决方案1】:

没有。它没有。它完全基于编译时评估。

你可以看到这个TryRoslyn example编译和反编译这个:

int name = 4;
string myStr = $"Hi {name}, how are you?";

进入这个:

int num = 4;
string.Format("Hi {0}, how are you?", num);

字符串插值也支持使用IFormattable作为结果所以(again using TryRoslyn)这个:

int name = 4;
IFormattable myStr = $"Hi {name}, how are you?";

变成这样:

int num = 4;
FormattableStringFactory.Create("Hi {0}, how are you?", new object[] { num });

【讨论】:

  • 谢谢!我正要问它是否完全等同于 String.Format 但这个 TryRoslyn 示例使一切变得更清楚:) 将尽快接受。
  • @i3arnon,我很惊讶$"Hi {0}, how are you?"; 编译并将0 作为string.Format 的参数。很明显为什么编译器允许您将代码放入:$"Hi {friend.GiveMeYourName()}, how are you?";。但是,输入数字的能力背后的推理非常有趣。
  • @LeonidVasilyev 为什么?这只是一种表达。为什么编译器的行为会有所不同?这将是一段有趣的代码,但编译器应该让你编写它。
  • @i3arnon name vs num - 错字?
  • @laktak 不,这是 TryRoslyn 工具的结果。数字可能是 num,因为它是 int
【解决方案2】:

This article 解释说它是基于编译时的(并在内部调用string.Format()。引用:

字符串插值在编译时进行转换,以调用等效的 string.Format 调用。这像以前一样保留了对本地化的支持(尽管仍然使用复合格式字符串),并且不会通过字符串引入任何编译后代码注入。

【讨论】:

    猜你喜欢
    • 2015-05-18
    • 2015-10-14
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多