Skip to content

Beginner · Arrays, strings and null · topic 11 of 43 · 30 min

Strings: methods, interpolation, verbatim and raw strings

Explanation

A string is a sequence of characters, and in C# strings are immutable: methods like ToUpper or Trim return a NEW string and leave the old one unchanged. Interpolated strings ($"...{value}...") build text with values and formats. Verbatim strings (@"...") keep backslashes as they are, and raw string literals ("""...""") hold quotes and many lines easily.

What is a string?

A string is text: a sequence of char values. You can read its length and each character by index, just like an array.

csharp
string city = "Bengaluru";
Console.WriteLine(city.Length);   // 9
Console.WriteLine(city[0]);       // B
Console.WriteLine(city[^1]);      // u
Console.WriteLine(city[0..4]);    // Beng
Ranges work on strings too and give a new string.

Immutable: strings never change

Immutable means "cannot be changed after it is made". Every string method that seems to change text actually builds a new string and returns it. If you do not store the result, nothing changes. This is the most common string bug.

csharp
string name = "  asha  ";
name.Trim();                 // result thrown away!
Console.WriteLine($"[{name}]");     // [  asha  ]
name = name.Trim().ToUpper();       // store the new string
Console.WriteLine($"[{name}]");     // [ASHA]
Always assign the result: name = name.Trim();

The most used methods

MethodExampleResult
ToUpper / ToLower"Pune".ToUpper()"PUNE"
Trim" hi ".Trim()"hi"
Contains"asha@okbank".Contains("@")true
StartsWith / EndsWith"INV-2041".StartsWith("INV")true
IndexOf"hello".IndexOf('l')2 (-1 if not found)
Substring(start, length)"9876543210".Substring(0, 5)"98765"
Replace"10-05-2026".Replace("-", "/")"10/05/2026"
Split"rice,dal,oil".Split(',')an array of 3 strings
string.Joinstring.Join(" | ", items)items joined by " | "
string.IsNullOrWhiteSpacestring.IsNullOrWhiteSpace(" ")true

Comparing strings

In C#, == compares the characters of two strings (unlike Java, where it compares references). But it is case-sensitive. For user input such as email addresses or coupon codes, compare without case.

csharp
string a = "Delhi", b = "delhi";
Console.WriteLine(a == b);                                              // False
Console.WriteLine(string.Equals(a, b, StringComparison.OrdinalIgnoreCase)); // True
Ordinal compares character codes, which is right for codes, ids and emails.

Interpolation and formats

Put $ before the opening quote and write any expression inside { }. After a colon you can add a format, and after a comma an alignment width.

csharp
decimal price = 1499.5m;
DateTime d = new DateTime(2026, 8, 15);
Console.WriteLine($"Price: {price:F2}");          // Price: 1499.50
Console.WriteLine($"Date: {d:dd-MM-yyyy}");       // Date: 15-08-2026
Console.WriteLine($"[{"Tea",-6}][{20,5}]");       // [Tea   ][   20]
F2: two decimals. dd-MM-yyyy: day-month-year. -6 pads on the right to width 6; 5 pads on the left.

Escape sequences and verbatim strings

csharp
string path1 = "C:\\Reports\\march.csv";   // \\ is one backslash
string path2 = @"C:\Reports\march.csv";    // verbatim: backslashes kept as typed
string quote = @"She said ""namaste""";    // in verbatim, "" is one quote
string twoLines = "Line 1\nLine 2";        // \n is a new line
A normal string uses \ for escape sequences: \n new line, \t tab, \" quote, \\ backslash. A verbatim string (@"...") turns escapes off, which suits Windows paths.

Raw string literals (C# 11 and later)

A raw string starts and ends with three or more double quotes. Inside it, quotes and backslashes need no escaping, and it can span many lines. The spaces before the closing """ are removed from every line, so you can indent it with your code.

csharp
string name = "Asha";
string json = $$"""
    {
      "name": "{{name}}",
      "city": "Pune"
    }
    """;
Console.WriteLine(json);
With $$, values go in double braces {{ }}, so single braces stay as plain JSON text.

Splitting and joining

csharp
string line = "Asha,21,Pune";
string[] parts = line.Split(',');
string name = parts[0];
int age = int.Parse(parts[1]);
Console.WriteLine($"{name} ({age}) from {parts[2]}");

string messy = "a,,b, c";
string[] clean = messy.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
Console.WriteLine(string.Join("|", clean));   // a|b|c
Split breaks text into an array. The options remove empty parts and trim spaces.

Common mistakes and fixes

  • Calling name.ToUpper(); without storing the result: strings are immutable. Write name = name.ToUpper();
  • Substring past the end: "abc".Substring(1, 5) throws ArgumentOutOfRangeException. Check Length first.
  • Comparing with == when case may differ: use StringComparison.OrdinalIgnoreCase.
  • Building a Windows path with single backslashes in a normal string: "C:\new" would contain a new line. Use @"..." or Path.Combine.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Strings: methods, interpolation, verbatim and raw strings · 1/7

Strings

In this lesson you will work with text: strings.

Prefer a video by a teacher? Find free videos on “C# string methods interpolation verbatim raw string literals tutorial” on YouTube ↗

In real life: Masking a mobile number on a receipt

Shops and banks print receipts that hide most of the customer's mobile number, showing only the first two and last two digits. A few string methods do this, and also clean up what the cashier typed.

csharp
string typed = "  98765 43210 ";
string mobile = typed.Replace(" ", "").Trim();

if (mobile.Length != 10 || !mobile.All(char.IsDigit))
{
    Console.WriteLine("Invalid mobile number");
    return;
}

string masked = mobile[..2] + new string('X', 6) + mobile[^2..];
Console.WriteLine($"Receipt sent to {masked}");
Shows Receipt sent to 98XXXXXX10. mobile.All(char.IsDigit) checks every character is a digit (All comes from LINQ, module 6).

Practice (0/4 done)

Task 1 · Question

string s = "Mumbai"; What is s.Substring(1, 3)?

Task 2 · Question

What does this print? string s = "chai"; s.ToUpper(); Console.WriteLine(s);

Task 3 · Question

What does "rice,dal,,oil".Split(',').Length give?

Task 4 · Practice

Write a method FormatName(string raw) that takes messy input like " rAVi kUMAR " and returns "Ravi Kumar": trim it, split on spaces (ignoring empty parts), make each word start with a capital and the rest small, and join with one space.

Quick quiz

Question 1

1.What does immutable mean for strings?

Question 2

2.Which string keeps C:\Temp\new.txt exactly as typed?

Question 3

3.decimal p = 5m; What is $"{p:F2}"?

Question 4

4.In C#, what does "abc" == "abc" compare?

Question 5

5."hello".IndexOf('z') returns...

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does immutable mean for strings?

Answer: Once made, a string's characters cannot change; methods return new strings

Every "change" creates a new string.

Which string keeps C:\Temp\new.txt exactly as typed?

Answer: @"C:\Temp\new.txt" with single backslashes inside

A verbatim string (@) turns off escape sequences, so \n stays as backslash-n.

decimal p = 5m; What is $"{p:F2}"?

Answer: 5.00

F2 means fixed-point with two decimals.

In C#, what does "abc" == "abc" compare?

Answer: The characters (the text)

For strings, == compares the text.

"hello".IndexOf('z') returns...

Answer: -1

-1 means the character was not found.

What does 'a,b,,c'.split(',') give?Related

Answer: ['a', 'b', '', 'c']

Two commas in a row make an empty string between them.

From Strings and template literals

What does strings.Fields(" a b ") return?Related

Answer: [a b]

Fields splits on runs of white space and drops empty parts.

From Strings, bytes and runes

Which gives the last character of the string text?Related

Answer: text.at(-1)

at(-1) counts from the end. text[-1] is undefined, there is no last() method, and slice(0, 1) gives the first character.

From Strings in depth

How many bytes does "UPI" occupy as a string literal?Related

Answer: 4

3 letters + the terminator.

From Strings are char arrays

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Arrays, strings and null” before its exam: StringBuilder and string performance, null, nullable types and null-safe operators.
  2. Module 3 exam: Arrays, strings and null · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Classes and objects. 43 topics left in the course before the final exam.

← Previous: Arrays: one name, many values