C#中的多行字符串:从hack到C# 11——完整指南

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

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

开始课程

曾经在Stack Overflow上:C#中长字符串的诅咒



想象一下这种情况。您正在用C#编写配置JSON、SQL查询,或者直接在代码中编写HTML模板。字符串变得很长、很难看,而且完全不可读。您按下回车键来换行……然后得到了一个编译错误。熟悉吗?



Stack Overflow上的问题"Multiline string literal in C#" 已经获得了数万次浏览。这并非偶然。长期以来,C#并不是一个对处理多行文本最友好的语言。但时代在变。在本文中,我们将走完从临时解决方案到C# 11中出现的优雅解决方案的历程。



如果您正在编写C#代码并处理多行字符串字面量,这篇文章将为您节省数小时的搜索时间。我们开始吧!



问题:为什么简单地按回车键是个坏主意?



在C#(以及C++)中,字符串字面量是用引号括起来的字符序列。在这些引号内换行是语法错误。编译器根本无法理解字符串在哪里结束。



以下是错误做法:



// 编译错误!string query = "SELECT * FROM UsersWHERE Age > 18ORDER BY Name";


编译器会看到"SELECT * FROM Users——然后就结束了。接下来就是一片混乱。过去,开发人员想尽办法来应对。让我们分析一下解决方案的演变过程。



旧方法:Verbatim string(@-字符串)——救星



首先想到的是verbatim string literal。您只需在左引号前加上@。这会禁用转义序列的解释(双引号""除外)。



但有一个问题:缩进也会成为字符串的一部分。



Verbatim string示例:



string json = @"{    ""name"": ""Alice"",    ""age"": 30}";Console.WriteLine(json);


输出:

{    "name": "Alice",    "age": 30}


优点:

  • 适用于所有C#版本。
  • 无需转义反斜杠(\\)。

缺点:

  • 内部的引号必须加倍("")——如果JSON很多,这很糟糕。
  • 左侧的缩进(空格/制表符)会进入最终字符串。
  • 不能直接与字符串插值($)混合使用(但可以使用$@)。


这种方法至今仍然流行,但对于干净的代码来说并不理想。真正的突破发生在C# 11。



最新方法:Raw string literal(C# 11 和 .NET 7+)



从C# 11开始,我们有了raw string literal——字面意思是“原始字符串字面量”。它解决了99%的多行字符串问题。



语法:连续三个或更多双引号(""")。



示例1:无需转义的简单JSON



string json = """    {        "name": "Alice",        "age": 30    }    """;Console.WriteLine(json);


输出:

{    "name": "Alice",    "age": 30}


神奇之处:字符串内部的引号无需加倍!编译器只有在看到连续三个引号时才会知道字符串结束。



示例2:带缩进的SQL查询



string query = """    SELECT         u.Name,        o.OrderDate    FROM Users u    JOIN Orders o ON u.Id = o.UserId    WHERE o.Status = 'Active'    ORDER BY o.OrderDate DESC    """;Console.WriteLine(query);


关于缩进的重要说明: 结束引号(""")设定了基本缩进级别。所有缩进少于结束引号的字符串行都将被修剪。这允许保持代码的可读性,同时避免用多余的空格弄乱字符串。

博客

书籍推荐