C# 中大括号的秘密:如何正确在 String.Format 中转义

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么 C# 中的大括号让人头疼?



您是否曾经编写过 C# 代码,想要输出类似 {名字}: {值} 的文本,却反而得到了 FormatException?如果是这样,您并不孤单。关于 “How to escape curly brace in String.Format” 的问题在 Stack Overflow 上获得了数万次浏览。这并非偶然:C# 中的大括号 {} 具有特殊含义——它们表示变量替换的位置。



但是,如果您需要将大括号本身作为普通字符输出,该怎么办?例如,用于 JSON、模板、代码生成或仅仅是为了美化报告格式?今天,我们将从头到尾讨论这个主题:从简单的转义到使用 StringBuilder 和字符串插值的高级技巧。



如何转义大括号:基本规则



答案简单而优雅:将大括号加倍。如果您想输出一个左大括号 {,请写 {{。对于右大括号 },请写 }}。C# 会理解这不是占位符,而是普通字符。



这是一个最简单的例子:



string result = string.Format("大括号中的值: {{0}}", 42);Console.WriteLine(result);// 输出: 大括号中的值: {0}


请注意:{{0}} 不是占位符,而是一对转义的大括号,里面包含数字 0。如果我们写 {0},则会得到变量的值(数字 42)。



新手典型错误



初学者经常这样写:



// 错误!string bad = string.Format("你好, {name}!", name);// FormatException: Input string was not in a correct format.


为什么?因为 C# 期望大括号内是数字索引({0}、{1}),而不是变量名。对于变量名,需要使用字符串插值(见下文)或显式指定索引。



实践示例:从简单到复杂



让我们分析几个需要转义大括号的真实场景。



1. 出于调试目的输出 JSON 或 XML



假设您正在编写一个日志记录器,并希望输出带有值替换的 JSON 字符串:



int userId = 101;string json = string.Format("{{\\"userId\\": {0}, \\"name\\": \\"Alice\\"}}", userId);Console.WriteLine(json);// 输出: {"userId": 101, "name": "Alice"}


这里的 {{ 和 }} 创建了 JSON 的外部大括号,而 {0} 替换为数字。



2. 生成代码模板



假设您正在用 C# 编写一个代码生成器。需要为另一种语言(例如 Python 或 JavaScript)创建一个包含模板的字符串:



string template = string.Format("def {0}():    return {{0}}", "calculate");Console.WriteLine(template);// 输出:// def calculate()://     return {0}


请注意:输出字符串中的 {{0}} 不再是 C# 的占位符,而是生成代码的一部分(例如,用于 Python)。



3. 混合多个占位符和大括号的格式化



当需要混合替换和转义时,关键是不要混淆索引:



string name = "Bob";int age = 30;string message = string.Format("用户 {{ {0} }} (年龄: {1})", name, age);Console.WriteLine(message);// 输出: 用户 { Bob } (年龄: 30)


这里的 {{ 产生 {,}} 产生 },而 {0} 和 {1} 替换为值。



String.Format 的替代方案:字符串插值和 StringBuilder



虽然 string.Format 是经典方法,但在现代 C# 中有更方便的方式。让我们比较一下。



字符串插值 (C# 6+)



字符串插值是在字符串前使用 $ 的魔法。它可读性更好,但大括号转义仍然存在

博客

书籍推荐