C# 6.0、.NET 4.51 和 VS2015 - 为什么字符串插值有效?

C# 6.0, .NET 4.51 and VS2015 - Why does string interpolation work?

阅读以下内容后:

在我看来,除了 String Interpolation 我在 VS2015 中针对 .NET 4.51 编译的任何项目都可以使用新的 C# 语言功能。

但是我在我的开发机器上使用 VS2015 目标 4.51 尝试了以下代码:

string varOne = "aaa";

string varTwo = $"{varOne}";

if (varTwo == "aaa")
{

}

而且我不仅没有收到编译器错误,而且它按预期工作,因为 varTwo 包含 aaa

谁能解释为什么会这样,因为我没想到它会起作用?我猜我错过了 FormattableString 的真正含义。有人可以给我举个例子吗?

Can someone explain why this is the case as I would not have expected this to work?

这是有效的,因为您正在使用 VS2015 附带的新 Roslyn 编译器进行编译,并且知道如何解析字符串插值语法糖(它只是调用 string.Format 的正确重载)。如果您尝试利用 .NET Framework 4.6 类,它可以很好地处理字符串插值,例如 FormattableString or IFormattable, you'd run into a compile time error (unless you add them yourself。请参阅 post) 的底部。

I am guessing I am missing what FormattableString really means.

FormattableString 是 .NET 4.6 中引入的新类型,它允许您将新的字符串插值功能与您选择的自定义 IFormatProvider 一起使用。由于这不能直接在内插字符串上完成,您可以利用可以传递任何自定义格式的 FormattableString.ToString(IFormatProvider)

如评论中所述,字符串插值在这种情况下有效,因为所有新编译器所做的就是在编译时将表达式转换为 "equivalent string.Format call"。

来自https://msdn.microsoft.com/en-us/magazine/dn879355.aspx

String interpolation is transformed at compile time to invoke an equivalent string.Format call. This leaves in place support for localization as before (though still with traditional format strings) and doesn’t introduce any post compile injection of code via strings.


FormattableString 是一个新的 class 允许您在渲染之前检查字符串插值,这样您就可以检查值并防止注入攻击。

// this does not require .NET 4.6
DateTime now = DateTime.Now;
string s = $"Hour is {now.Hour}";
Console.WriteLine(s);

//Output: Hour is 13

// this requires >= .NET 4.6
FormattableString fs = $"Hour is {now.Hour}";
Console.WriteLine(fs.Format);
Console.WriteLine(fs.GetArgument(0));

//Output: Hour is {0}
//13