博客 / 詳情

返回

C# 原始字符串字面量全面解析:多行字符串終於優雅了!

簡介

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 查詢:編寫多行數據庫查詢

  • 代碼生成:創建模板化代碼
  • 文檔字符串:編寫格式化的文檔
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.