插值字符串格式问题

时间:2018-05-28 17:49:58

标签: 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}”

如果没有像下面那样做一些hackish,这有可能吗?

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

2 个答案:

答案 0 :(得分:4)

这是字符串插值的预期行为。在this Microsoft文档中提到了它。以下内容仅来自Microsoft链接。

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

解释转义大括号的方式会导致意外结果。例如,考虑格式项" {{{0:D}}}",它用于显示左大括号,格式化为十进制数的数值和右大括号。但是,格式项实际上是按以下方式解释的:

  • 前两个开口大括号("{{")被转义并产生一个 开口大括号。
  • 接下来的三个字符("{0:")被解释为a的开头 格式项目。
  • 下一个字符("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}  

答案 1 :(得分:2)

假设不需要使用命名格式字符串,您可以使用:

var s = $"{{{number:#.#0}}}";
相关问题