c# - 内插字符串格式问题

标签 c# .net c#-6.0

我已经多次偶然发现一个与内插字符串有关的问题。

考虑以下情况:

double number = 123.4567;
var str = $"{{{number:F2}}}"; //I want to get "{123.45}"
Console.WriteLine(str); // Will print "{F2}"

起初有点令人惊讶,但一旦您意识到大括号是如何配对的,它就很有意义了。接下来的两个大括号是内插字符串中单个大括号的转义序列。因此,内插表达式的左括号与字符串中的最后一个花括号配对。

     ___pair____
    |           |
$"{{{number:F2}}}";

现在您可以执行以下操作来中断转义序列:

var str = $"{{{number:F2} }}"; // This will be "{123.45 }"

注意此方法添加到输出中的空格字符。 (不理想)

我的问题:

假设我想使用单个内插字符串来准确获得输出“{123.45}”

如果不做像下面这样的骇人听闻的事情,这是完全可能的吗?

var s = $"{{{number:F2}{'}'}";

最佳答案

这是字符串插值的预期行为。在 this 中提到微软文档。以下内容仅来自微软链接(soft link)。

左大括号和右大括号被解释为格式项的开始和结束。因此,您必须使用转义序列来显示原义的左大括号或右大括号。在固定文本中指定两个左大括号("{{")以显示一个左大括号("{"),或两个右大括号("}} ") 显示一个右大括号 ("}")。格式项中的大括号按遇到它们的顺序依次解释。不支持解释嵌套大括号。

转义大括号的解释方式可能会导致意想不到的结果。例如,考虑格式项“{{{0:D}}}”,它旨在显示左大括号、格式化为十进制数字的数值和右大括号。然而,格式项实际上是按以下方式解释的:

  • 前两个左大括号 ("{{") 被转义并产生一个 左括号。
  • 接下来的三个字符 ("{0:") 被解释为一个 格式项。
  • 下一个字符 ("D") 将被解释为十进制标准 数字格式说明符,但接下来的两个转义大括号 ("}}") 产生一个大括号。因为生成的字符串 ("D}") 不是 标准数字格式说明符,结果字符串是 解释为自定义格式字符串,表示显示文字 字符串 "D}".
  • 最后一个大括号 ("}") 被解释为格式项的结尾。
  • 显示的最终结果是文字字符串,"{D}"。这 不显示要格式化的数值。

编写代码以避免误解转义大括号和格式项的一种方法是分别格式化大括号和格式项。也就是说,在第一个格式化操作中显示文字左大括号,在下一个操作中显示格式项的结果,然后在最后一个操作中显示文字右大括号。以下示例说明了这种方法。

int value = 6324;
string output = string.Format("{0}{1:D}{2}", 
                             "{", value, "}");
Console.WriteLine(output);
// The example displays the following output:
//       {6324}  

关于c# - 内插字符串格式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50571391/

相关文章:

c# - 如何使用 INamingContainer 创建自定义控件?

c# - 进入垃圾邮件文件夹的电子邮件

c# - 合并两个 IGrouping 集

.net - .net 有没有类似 Vaadin 的东西?

C# 6 自动初始化属性和支持字段的使用

c# - 具有空传播的事件引发的线程安全

c# - 如何使 UI 在 Winforms 中响应

c# - 带锁的单例属性如何保证线程安全?

c# - System.Text.Json.JsonException : A possible object cycle was detected

c# - 运算符(operator) ?。和扩展方法