簡介
C# 11 引入了原始字符串字面量(Raw String Literals),這是一個革命性的特性,極大地簡化了包含大量特殊字符(如引號、反斜槓、換行符等)的字符串處理。
原始字符串字面量允許創建包含任意文本的字符串,而無需轉義特殊字符。它們以至少三個雙引號 """ 開始和結束,並且可以跨越多行。
核心特性與優勢
核心特點
- 無轉義需求:不需要對引號、反斜槓等特殊字符進行轉義
- 多行支持:原生支持多行字符串格式
- 空白保留:精確保留源代碼中的縮進和格式化
- 靈活分隔符:使用可變數量的雙引號作為分隔符
- 字符串插值:可與插值語法無縫結合
與傳統字符串對比
| 特性 | 常規字符串 | 逐字字符串(@) | 原始字符串字面量 |
|---|---|---|---|
| 轉義需求 | 需要轉義特殊字符 | 不需要轉義,但對雙引號仍需轉義 | 完全不需要轉義 |
| 多行支持 | 需使用\n等 |
支持 | 原生支持 |
| 縮進保留 | 不保留 | 保留所有縮進 | 智能縮進處理 |
| 引號處理 | \" |
"" |
直接使用 |
| JSON/XML | 可讀性差 | 可讀性中等 | 完美呈現 |
基本語法
// 基本原始字符串
string basic = """這是一個原始字符串,不需要轉義 "引號" 和 \反斜槓""";
// 多行原始字符串
string multiLine = """
這是一個
多行原始字符串
可以包含 "引號" 和 \反斜槓
""";
// 包含大括號的原始字符串
string withBraces = """
{ "name": "John", "age": 30 }
""";
核心特性與優勢
無需轉義特殊字符
// 傳統方式(需要轉義)
string traditional = "這是一個包含\"引號\"和\\反斜槓的字符串";
// 原始字符串方式(無需轉義)
string raw = """這是一個包含"引號"和\反斜槓的字符串""";
// 正則表達式示例
string regexPattern = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$""";
多行字符串處理
// 傳統多行字符串(需要轉義和連接)
string oldMultiLine = "第一行\n" +
"第二行\n" +
"第三行";
// 原始多行字符串(更簡潔)
string newMultiLine = """
第一行
第二行
第三行
""";
// JSON 示例
string json = """
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
""";
縮進處理
原始字符串字面量會自動處理縮進,使代碼保持整潔:
string GetFormattedMessage()
{
return """
Hello,
This is an indented message.
It preserves the formatting exactly as written.
""";
}
// 輸出結果:
// Hello,
// This is an indented message.
// It preserves the formatting exactly as written.
引號數量規則
當字符串內容包含三個或更多連續雙引號時,需要使用更多引號作為分隔符:
// 內容包含三個雙引號 → 使用四個作為分隔符
string tripleQuotes = """" 這裏可以包含 """ 三個引號 """";
// 內容包含四個雙引號 → 使用五個作為分隔符
string fourQuotes = """"" 這裏可以包含 """" 四個引號 """"";
引號數量選擇原則
- 分隔符的雙引號數量(N)必須大於內容中連續雙引號的最大數量(M)
- 最小分隔符數量為3(即使內容沒有三個引號)
- 公式:
N > M
多$符號規則
$的數量決定了插值表達式的邊界- 一個
$→ 表達式使用{ } - 兩個
$$→ 表達式使用{{ }},以此類推
高級用法與技巧
包含更多引號
如果需要字符串中包含三個或更多連續雙引號,可以使用更多引號作為分隔符:
// 使用四個引號作為分隔符,以包含三個引號
string withTripleQuotes = """"
這個字符串包含三個連續引號: """
"""";
// 使用五個引號作為分隔符,以包含四個引號
string withFourQuotes = """""
這個字符串包含四個連續引號: """"
""""";
與字符串插值結合使用
原始字符串可以與字符串插值結合使用,提供更強大的功能:
string name = "John";
int age = 30;
// 基本插值
string interpolated = $$"""
{
"name": "{{name}}",
"age": {{age}}
}
""";
// 複雜插值(使用多個$符號)
string complex = $$$"""
{
"name": "{{{name}}}", // 注意:這裏需要三個大括號
"age": {{age}}
}
""";
最小化縮進
原始字符串會自動去除與結束引號對齊的縮進:
string minimalIndent = """
First line
Second line
Third line
"""; // 結束引號的縮進決定了最小縮進
// 等效於:
// "First line\nSecond line\nThird line"
實際應用場景
JSON 和 XML 處理
// JSON 配置
string configJson = """
{
"appSettings": {
"timeout": 30,
"retryCount": 3,
"apiUrl": "https://api.example.com"
},
"logging": {
"level": "Information",
"filePath": "logs/app.log"
}
}
""";
// XML 文檔
string xmlDocument = """
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with XML.</description>
</book>
</catalog>
""";
正則表達式模式
// 複雜的正則表達式(無需轉義反斜槓)
string emailPattern = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$""";
string phonePattern = """^(\+\d{1,3}\s?)?(\(\d{1,4}\)\s?)?\d{1,4}[\s.-]?\d{1,4}[\s.-]?\d{1,9}$""";
// 使用正則表達式
bool isValidEmail = Regex.IsMatch("test@example.com", emailPattern);
SQL 查詢
string sqlQuery = """
SELECT
u.Id,
u.Name,
u.Email,
COUNT(o.Id) AS OrderCount
FROM Users u
LEFT JOIN Orders o ON u.Id = o.UserId
WHERE u.IsActive = 1
GROUP BY u.Id, u.Name, u.Email
HAVING COUNT(o.Id) > 0
ORDER BY OrderCount DESC
""";
代碼生成
string GenerateCSharpClass(string className, IEnumerable<string> properties)
{
return $$"""
public class {{className}}
{
{{string.Join("\n ", properties.Select(p => $"public string {p} {{ get; set; }}"))}}
public {{className}}()
{
}
public override string ToString()
{
return $"{{
{{string.Join(", ", properties.Select(p => $"{p}={{{p}}}"))}}
}}";
}
}
""";
}
// 使用示例
string classCode = GenerateCSharpClass("Person", new[] { "FirstName", "LastName", "Age" });
總結
C# 11 的原始字符串字面量是一個強大的特性,它:
- 消除轉義需求:無需轉義引號、反斜槓等特殊字符
- 支持多行內容:輕鬆創建多行字符串,保持格式
- 智能縮進處理:自動處理縮進,使代碼更整潔
- 與插值結合:支持字符串插值,創建動態內容
- 編譯時處理:無運行時性能開銷
適用場景:
JSON/XML/HTML內容:處理結構化數據- 正則表達式:編寫複雜的模式匹配
SQL 查詢:編寫多行數據庫查詢
- 代碼生成:創建模板化代碼
- 文檔字符串:編寫格式化的文檔