Hello! Welcome to your seventh and final lesson in our first module on C#'s core types.
In our last lesson, we covered the nuances of type checking and casting using is and as, focusing on the modern, safe, and readable patterns that C# offers. This wrapped up our deep dive into how C# handles types at runtime.
Today, we'll focus on a feature you'll use constantly: string manipulation. The learning outcome is to use string interpolation and verbatim strings for effective string formatting.
As a developer working with ASP.NET, you're no stranger to building strings for logs, API responses (like JSON), or UI messages. Coming from Java and older C# code, you're likely familiar with methods like string.Format() or manual concatenation with +. However, modern C# provides much more elegant and powerful tools. This lesson will not only show you what they are but, crucially for your goal of mastery, how they work under the hood and why they are more efficient.
1. Verbatim Strings: Handling Text Literally
Let's start with a feature that helps clean up code dealing with special characters: the verbatim string literal, denoted by the @ prefix.
A regular string literal interprets backslashes as escape characters. This is often problematic for file paths or regular expressions. A verbatim string treats backslashes as literal characters.
Regular string:
string path = "C:\\Users\\MyUser\\Documents";
Verbatim string:
string path = @"C:\Users\MyUser\Documents";
Verbatim strings also allow for multi-line text without needing concatenation or escape characters for new lines.
The primary drawback is that if you need to include a double-quote character (") within a verbatim string, you must escape it by doubling it (""), which can become cumbersome.
The following short video segment explains this concept clearly.
New-ish Things about C# Strings (C# 11)
In the video 'New-ish Things about C# Strings', Deborah Kurata provides a concise overview of verbatim strings and their limitations.
Watch the segment from 00:41 to 02:00. Pay attention to how verbatim strings handle multi-line text and the problem with indentation and embedded quotes.
2. String Interpolation: The Modern Standard
The most significant improvement to string formatting in C# is string interpolation, introduced in C# 6 and denoted by a $ prefix. It allows you to embed expressions directly into a string literal, making the code dramatically more readable than string.Format().
The old way (string.Format):
string name = "Alice";
int age = 30;
string message = string.Format("User {0} is {1} years old.", name, age);
The modern way (string interpolation):
string name = "Alice";
int age = 30;
string message = $"User {name} is {age} years old.";
The difference in readability is immediate. You no longer need to match numbered placeholders to a list of arguments.
For a great introduction that contrasts the old and new ways, please watch this video.
Filip Ekberg's 'String Interpolation in C#' video does an excellent job of showing the pain points of string.Format and how interpolation solves them.
Watch from the beginning to 04:02. This will cover: The maintenance issues with string.Format. The basic syntax of string interpolation. How to apply formatting specifiers (e.g., for dates and numbers) within an interpolated string.
As the video shows, any valid C# expression can be placed within the curly braces {}, including method calls, property access, and calculations. You can also combine interpolation with verbatim strings for multi-line interpolated text using $@ or @$.
string newStuff = "Fixed a bug.";
string message = $@"Version 1.1 is now available.
New features:
- {newStuff}
- {DateTime.Now:yyyy-MM-dd}: Release date.
";
3. Under the Hood: The Evolution of Interpolation
This is where things get interesting and align with your goal to understand C#'s internal workings. String interpolation is syntactic sugar—a language feature that the compiler transforms into more fundamental code.
The C# 6 Story: string.Format
Initially, the compiler simply rewrote an interpolated string into a string.Format() call. The following resource shows exactly how this works.
Back to Basics: String Interpolation in C#
Rick Strahl's blog post, 'Back to Basics: String Interpolation in C#,' provides excellent detail on this compile-time transformation.
Read the sections 'Interpolated Strings are not a Template Solution,' 'Interpolated Strings must be Static String Literals,' and 'Looking at the IL Code.' These sections explain that interpolation is a compile-time feature and show the resulting Intermediate Language (IL) code, which reveals the underlying string.Format call.
While convenient, this approach inherited the performance issues of string.Format, namely:
- Boxing: Value types (like
int,DateTime) passed as arguments must be converted toobject, causing a small memory allocation on the heap. - Array Allocation: If more than three arguments are used, an
object[]array is allocated to hold them.
The C# 10 / .NET 6+ Story: Interpolated String Handlers
Recognizing these performance costs, C# 10 introduced a groundbreaking optimization: interpolated string handlers. When compiling code that targets .NET 6 or newer, the compiler can now transform an interpolated string into a highly efficient, builder-like pattern that avoids allocations.
This is a significant detail for a developer aiming for mastery, as it explains why modern C# is much faster at string construction than it used to be.
String Interpolation in C# 10 and .NET 6
The official .NET Blog post 'String Interpolation in C# 10 and .NET 6' is the definitive source for this topic. It's a deep dive that's perfect for understanding the 'why' behind the change.
Please read these two key sections: Start by finding the list of limitations of String.Format. This section clearly outlines the performance problems (boxing, array allocation, etc.). Continue to the next section, 'Strings, But Faster', which explains how interpolated string handlers work. Focus on the 'before' and 'after' code examples and the performance benchmark results. This clearly demonstrates the elimination of boxing and array allocations.
In short, modern C# string interpolation gives you the readability of inline expressions with performance that can approach manual StringBuilder usage, all handled by the compiler.
4. The Latest Evolution: Raw String Literals (C# 11)
C# 11 introduced raw string literals to solve the last few annoyances with verbatim strings, namely escaping quotes and managing indentation. A raw string literal begins and ends with at least three double quotes (""").
Key advantages:
- No escaping of any characters is needed, including double quotes.
- The indentation of your code doesn't affect the output string's indentation. The final indentation is determined by the position of the closing
""".
This is incredibly useful for embedding code snippets, JSON, or XML directly in your C# files.

Even better, raw strings can be interpolated. If your content contains curly braces {} (like in JSON), you can use multiple dollar signs ($$) to tell the compiler that only double curly braces {{...}} represent an interpolated expression.
The following video is the best resource to see all these modern features in action.
New-ish Things about C# Strings (C# 11)
Deborah Kurata's video on 'New-ish Things about C# Strings' is an excellent tour of these C# 11 features.
Please watch these two segments: 02:00 - 04:51: This covers raw string literals, explaining the syntax and how they handle indentation and embedded quotes. 07:22 - 08:33: This demonstrates raw string interpolation, including the powerful multi-dollar-sign syntax for handling embedded curly braces.
5. Practice Exercise
Let's apply these modern techniques to a practical scenario. Your task is to generate a JSON string representing a user object. Use a raw interpolated string literal to achieve this.
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public DateTime CreatedAt { get; set; }
}
var user = new User { Id = 101, Username = "test.user", CreatedAt = new DateTime(2023, 10, 27) };
// TODO: Create the JSON string for the 'user' object using a raw interpolated string.
// The output should look exactly like this (including indentation):
// {
// "id": 101,
// "username": "test.user",
// "creationDate": "2023-10-27"
// }
string jsonString = ""; // Replace with your implementation
Console.WriteLine(jsonString);
Think about how you can use a raw string to handle the multi-line format and quotes, and how interpolation can insert the user's data. You will also need to format the CreatedAt date.
Click for a solution
string jsonString = $$"""
{
"id": {{user.Id}},
"username": "{{user.Username}}",
"creationDate": "{{user.CreatedAt:yyyy-MM-dd}}"
}
""";
Explanation:
$$"""starts a raw interpolated string where{{...}}is used for expressions. This is necessary because JSON itself uses single curly braces{}for its structure.- The indentation of the content is preserved relative to the closing
""". - The
user.Idis a number, so it doesn't need quotes in the JSON. - The
user.Usernameis a string, so it's enclosed in quotes ("...") within the JSON structure. - The
user.CreatedAtdate is formatted toyyyy-MM-ddusing a format specifier.
Conclusion
This lesson concludes our first module on C#'s core types and memory model. You are now equipped with the modern, idiomatic C# syntax for formatting strings efficiently and readably.
Key Takeaways:
- Verbatim Strings (
@): Useful for file paths and simple multi-line strings, but can be clumsy with quotes. - String Interpolation (
$): The default choice for embedding values into strings due to its superior readability overstring.Format. - Under the Hood: Interpolation has evolved from a simple wrapper around
string.Formatto a highly-optimized, allocation-free mechanism in modern .NET thanks to interpolated string handlers. - Raw String Literals (
"""): The best tool for complex, multi-line string content like JSON or XML, especially when combined with interpolation ($$"""...""").
Preview of the Next Module:
We've built a strong foundation. In our next module, "Modern Data Structures: Classes, Structs, and Records," we'll move up a level of abstraction. The very first lesson will be on how to define auto-implemented properties with get and set accessors, a fundamental building block for creating clean and maintainable data types in C#.