C#11原始字符串要求结尾"""必须顶格,否则因缩进不一致报错CS8951;插值用{{}}转义,内容含"""需用≥4个引号包裹;缩进裁剪仅删每行开头公共空白,首末行不参与计算。

原始字符串字面量不是语法糖,是 C# 11 起必须用的硬性能力——如果你还在手动拼 @"" 或逃 "\",说明你正把 JSON、SQL、正则写成维护噩梦。
为什么 """ 结尾必须顶格?
编译器靠结尾 """ 所在行的前导空白(空格或制表符)来决定“剪掉多少缩进”。如果结尾行有 4 个空格,那所有内容行开头的 4 个空格都会被自动剔除;但如果结尾行混了空格和制表符,或末尾带注释,""" 就不被识别为终止符,直接报错 CS8951。
- 结尾
"""行不能有任何其他字符(包括// comment) - 同一原始字符串内,缩进只能用空格 *或* 制表符,不能混用
- 最稳妥写法:开头
"""和结尾"""都独占一行、无任何前置空白
$""" 插值时大括号怎么写才不翻车?
插值原始字符串里,{ 和 } 本身是插值语法标记,但你想字面输出 {(比如 JSON 开头),就得转义——不是用反斜杠,而是双写:{{ 和 }}。否则编译器会误判为插值表达式起点,报错 CS1056(意外字符 {)。
- 要输出单个
{,写{{;要输出{{,写{{{{ - 变量插值照常写:
$"""Hello {name}"""是合法的 - 嵌套插值不支持,
$"""Value: {{$value}}"""会报错,得拆成两层字符串拼接
字符串里真要包含 """ 怎么办?
原始字符串的终止符是连续三个双引号,所以内容里出现 """ 会提前截断。解决办法是“加引号”:用更多双引号扩展边界。规则很简单——开头用 N 个 ",结尾也必须用 N 个,且 N ≥ 4;内容里的 """ 就自然被包住。
- 写
"""""This is """inside"""""→ 得到字符串This is """inside - SQL 中字段名含三个引号?用
""""""包一层:SELECT """""id""""" FROM users - 别试图用
@""""""混搭,@前缀对原始字符串无效
多行 SQL 或 JSON 缩进后实际内容怎么算?
原始字符串保留所有换行和空格,但“智能缩进裁剪”只发生在结尾 """ 行有前导空白时。它只剪每行开头的**公共最小前导空白**,首行(""" 后第一行)和末行(""" 前最后一行)不参与计算,空行会被跳过。
- 下面这个
sql字符串实际值是"SELECT *\nFROM Users\nWHERE id = 1"(无首尾空格,中间换行保留) - 如果结尾
"""前有 2 个空格,那每行开头的 2 个空格全被删,但行中或行尾空格不动 - 调试时不确定结果?打断点看
sql.Length和逐字符检查,比猜缩进更可靠
最易被忽略的是:原始字符串的缩进裁剪逻辑和 IDE 自动缩进不联动——你靠 Tab 对齐代码,编译器只认结尾 """ 行的空白字符数量。写完务必检查那一行是不是真的“左对齐”。


















