﻿# 彙整從 C# 1.0 到 C# 11.0 的字串格式變化

我昨天在整理 C# 到底有多少字串的表示法，原本想說應該五六個吧，整理到越後面越多，整理出了 `11` 種不同的語法，真的到了讓人眼花撩亂的地步。今天這篇文章就我就整理一下我的研究心得。

![C# Strings](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/a026f3b3161642875c9b-211361798-f87aa474-89b6-4352-9014-b911afd7bbbc.png)

我從 [The history of C#](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history) 與 [C# reference](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/?WT.mc_id=DT-MVP-4015686) 特別翻出了特定 C# 語法的版本資訊，以下從舊版到新版整理給大家參考。

-   C# 1.0 Regular string literals
    
    最原始的字串表示法，遇到雙引號要改用 `\"` 才行！
    
    ```csharp
    string name = "you";
    
    string s1 = "I think \r\n  \"" + name + "\"\r\nare awesome!";
    s1.Dump("C# 1.0 Regular string literals- \"\"");
    ```
    
    ![C# 1.0 Regular string literals](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/d3aa1b4d57bd210d0257-211362368-cf89632e-cf2a-4a4e-aa43-3d95240b6099.png)
    
-   C# 1.0 Verbatim string literals
    
    你可以直接在字串中加入「斷行符號」且不需要用 `\r\n` 跳脫字元，但雙引號要改用 `""` 才行！
    
    ```csharp
    string s2 = @"I think
      """ + name + @"""
    are awesome!";
    s2.Dump("C# 1.0 Verbatim string literals - @\"\" - Multiline");
    ```
    
    ![C# 1.0 Verbatim string literals](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/bed4bc64979ef0ebbe98-211362431-4fcabd0d-4b33-47ca-8ec7-717c1a0642f0.png)
    
-   C# 6.0 Interpolated Strings
    
    透過 `$"..."` 可以做到「字串內插」的表達方式，字串中的 `{name}` 可以用來插入其他變數！
    
    ```csharp
    string name = "you";
    
    string s3 = $"I think \r\n  \"{name}\"\r\nare awesome!";
    s3.Dump("C# 6.0 Interpolated Strings - $\"\"");
    ```
    
    ![C# 6.0 Interpolated Strings](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/cc3f1d4203faf7e87e74-211362484-1d8538a2-b84e-49b2-b476-286601d18290.png)
    
-   C# 8.0 Interpolated Verbatim Strings
    
    你可以使用 `@$"..."` 或 `$@"..."` 語法，混合 `Verbatim string literals` 與 `Interpolated Strings` 的表達方式！
    
    ```csharp
    string name = "you";
    
    string s4 = $@"I think
      ""{name}""
    are awesome!";
    s4.Dump("C# 8.0 Interpolated Verbatim Strings - $@\"\"");
    
    string s5 = @$"I think
      ""{name}""
    are awesome!";
    s5.Dump("C# 8.0 Interpolated Verbatim Strings - @$\"\"");
    ```
    
    ![C# 8.0 Interpolated Verbatim Strings](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/0ad4bbb89e928f48e13d-211362580-67cbd1eb-884a-4916-a514-234728cc383a.png)
    
-   C# 10.0 Constant interpolated strings
    
    你可以將字串設定為 `const` (常數) 時，也同時使用 `$` 字串內插的表達方式！
    
    ```csharp
    const string Language = "C#";
    const string Platform = ".NET";
    const string Version = "10.0";
    const string s6 = $"{Platform} - Language: {Language} Version: {Version}";
    s6.Dump("C# 10.0 Constant interpolated strings - const string x = $\"\"");
    ```
    
    ![C# 10.0 Constant interpolated strings](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/10c2d99a79cc85e9d1e7-211362656-62daace8-cf1c-4962-844f-646de908a9f9.png)
    
-   C# 11.0 Raw string literal
    
    終於可以在 C# 寫雙引號不用寫成 `\"` 或 `""` 的樣子了，這樣蠻好的！
    
    ```csharp
    string s7 = """
                I think "you" are awesome!
                """;
    s7.Dump("C# 11.0 Raw string literal - Multiline");
    
    string s8 = """I think "you" are awesome!""";
    s8.Dump("C# 11.0 Raw string literal - Singleline");
    ```
    
    ![C# 11.0 Raw string literal](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/02343ecc247196077d2e-211362754-a89fd378-679f-45a5-9c18-f485616f8f44.png)
    
    > 如果你要在 C# 字串中寫上 JSON 內容，且包含很多 `{` 或 `}` 符號時，透過這種於法也可以很乾淨的書寫！👍
    
-   C# 11.0 Interpolated raw string literal
    
    如果你想在這種格式加入「內插變數」的功能，字串前面加上一個 `$` 符號即可使用 `{name}` 語法來內插變數，不過這種用法就無法輸出 `{` 與 `}` 符號到字串中了：
    
    ```csharp
    string s9 = $"""
                I think "{name}" are awesome!
                """;
    s9.Dump("C# 11.0 Interpolated raw string literal - Multiline");
    ```
    
    ![C# 11.0 Interpolated raw string literal](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/0342b9b68553d6c09a29-211364375-bfade129-ae83-4628-b366-8428ab353ce0.png)
    
    如果你想在這種格式插入 `"""` 字元的話，其語法就相當特殊，你必須插入 `{"\"\"\""}` 才行：
    
    ```csharp
    string s9_1 = $"""
                {"\"\"\""}
                I think "{name}" are awesome!
                {"\"\"\""}
                """;
    s9_1.Dump("C# 11.0 Interpolated raw string literal - Multiline & Escape \"\"\"");
    ```
    
    要輸出 `{` 或 `}` 大括弧符號且又想**內插變數**的話，就要改用 `$$` 來改變對大括弧的解析方式，但之後若要內插變數就要改變語法，使用 `{{name}}` 這種方式內插變數！
    
    ```csharp
    string s10 = $$"""
                I think "{name}" are awesome!
                I think "{{{name}}}" are awesome!
                """;
    s10.Dump("C# 11.0 Interpolated raw string literal - Multiline - Direct output { and }");
    ```
    
    > 有趣的地方是，如果你想用 `{{{name}}}` 來內插變數，可以使用 `$$$` 來改變對大括弧的解析方式，以此類推下去，你的字串語法會變的非常詭異，哈！😆
    
    ![C# 11.0 Interpolated raw string literal](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/ad4c1cbaa3f80ba893ed-211364417-5b6b1aa6-e707-45a5-a2b9-3ae605fcbecf.png)
    
-   C# 11.0 UTF-8 string literals
    
    若要將一個 UTF-8 字串使用 `ReadOnlySpan<byte>` 來表達，在 C# 11.0 有個相當簡潔的語法，你可以直接在字串後面加上 `u8` 結尾，就可以指派給一個 `ReadOnlySpan<byte>` 型別的變數！
    
    ```csharp
    ReadOnlySpan<byte> s11 = ("AUTH "u8);
    s11.Dump("C# 11.0 UTF-8 string literals");
    
    byte[] s11_byteArray = ("AUTH "u8).ToArray();
    s11_byteArray.Dump("C# 11.0 UTF-8 string literals to Byte Array");
    ```
    
    ![C# 11.0 UTF-8 string literals](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/171e807fd296fdbf8d62-211362875-e69793ac-a9cb-4dd6-bd0e-1e0318ee96e2.png)
    

### 相關連結

-   [The string type | Built-in reference types - C# reference | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types?WT.mc_id=DT-MVP-4015686#the-string-type)
-   [C# Special Characters](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/?WT.mc_id=DT-MVP-4015686)
-   [String interpolation using $](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated?WT.mc_id=DT-MVP-4015686)
-   [Verbatim text - @ in variables, attributes, and string literals](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim?WT.mc_id=DT-MVP-4015686)
-   [Raw string literal text - """ in string literals](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/raw-string?WT.mc_id=DT-MVP-4015686)
-   [C# Language Specifications](https://csharpindepth.com/articles/Specifications)
