C# 11 Raw String Literals for Multi-Line and JSON

C# 11 introduced raw string literals, a feature designed to drastically simplify how developers write multi-line strings and embed text formats like JSON, XML, or SQL. By removing the need to escape special characters like quotation marks and backslashes, raw string literals make code cleaner, more readable, and less error-prone. This article explores how raw string literals work, how they manage indentation, and how features like multi-dollar-sign interpolation streamline JSON handling in modern C# applications.

The Pain Point of Traditional Strings

Before C# 11, embedding JSON or multi-line strings required either traditional escape sequences or verbatim string literals (@""). Both approaches introduced friction:

  • Escape sequences: Embedding JSON required escaping every double quote ("{\"name\": \"John\"}"), destroying readability.
  • Verbatim strings: While verbatim strings support multi-lines, nested quotes required double escaping (@"{ ""name"": ""John"" }"), and leading whitespace was rigidly tied to the string's actual code indentation.

How Raw String Literals Work

Raw string literals begin and end with a sequence of at least three double-quote characters ("""). Any character inside this boundary is interpreted literally, meaning backslashes (\) and quotation marks (") do not require escaping.

string simple = """This is a "raw" string literal without escapes.""";

For multi-line strings, the opening delimiter must be the last token on its line, and the closing delimiter must be the first token on its line:

string multiLine = """
    Line 1
    Line 2
    Line 3
    """;

Automatic Indentation Stripping

A major advantage of raw string literals is indentation management. The horizontal position of the closing delimiter (""") defines the baseline margin for the entire string. Any whitespace to the left of the closing delimiter's column position is automatically trimmed from every line in the output. This allows you to indent strings naturally alongside your C# code without adding unwanted spaces to the resulting data.

Simplifying JSON Handling

Raw string literals eliminate the messy syntax traditionally associated with defining mock data, payloads, or schemas in code. You can paste standard JSON directly into a C# file without modification:

string jsonPayload = """
    {
      "id": 101,
      "title": "Raw String Literals",
      "status": "Published"
    }
    """;

Handling Interpolation in JSON with Multiple $ Characters

A common problem when generating JSON dynamically is that JSON syntax relies heavily on curly braces ({ and }), which conflict with C#'s standard string interpolation ($"").

C# 11 solves this by allowing multiple dollar signs ($$, $$$, etc.) before the raw string literal. The number of dollar signs dictates how many consecutive braces are required to trigger interpolation:

int userId = 42;
string role = "Admin";

// Two '$' symbols mean '{{' and '}}' are used for interpolation.
// Single '{' and '}' are treated as literal JSON braces.
string dynamicJson = $$"""
    {
      "userId": {{userId}},
      "role": "{{role}}"
    }
    """;

By requiring matching brace counts for expressions, raw string literals eliminate the need to escape single braces ({{ and }}) throughout entire JSON bodies.

Key Takeaways

  • No Escaping Needed: Quotation marks and backslashes are read as raw text.
  • Clean Formatting: Closing delimiter alignment controls multi-line indentation.
  • Seamless JSON Interpolation: Using multiple $ symbols decouples C# expressions from JSON curly brackets, making inline payload generation clean and intuitive.