.NET Academy

Working with strings

Build, inspect and transform text with string methods, interpolation and StringBuilder.

12 min read

You will learn

  • Access characters and lengths of strings
  • Use the most common string methods
  • Format values with interpolation and format specifiers
  • Understand why strings are immutable and when to use StringBuilder

Strings are sequences of characters

A string holds text. Under the hood it's a sequence of char values that you can inspect:

string word = "C# rocks";
 
Console.WriteLine(word.Length);   // 8
Console.WriteLine(word[0]);       // 'C' — indexes start at 0
Console.WriteLine(word[^1]);      // 's' — ^1 means "first from the end"
Console.WriteLine(word[3..]);     // "rocks" — a range from index 3 to the end

Strings are immutable

Once created, a string never changes. Methods that seem to modify a string actually return a new one:

string name = "ada";
name.ToUpper();                 // creates "ADA"… and throws it away
Console.WriteLine(name);        // ada
 
name = name.ToUpper();          // keep the result
Console.WriteLine(name);        // ADA

Watch out

Forgetting to use the returned value is a very common bug: text.Trim(); on its own line does nothing useful.

The methods you'll use constantly

MethodExampleResult
ToUpper() / ToLower()"Hi".ToUpper()"HI"
Trim()" hi ".Trim()"hi"
Contains(x)"hello".Contains("ell")true
StartsWith(x) / EndsWith(x)"file.cs".EndsWith(".cs")true
IndexOf(x)"hello".IndexOf('l')2 (or -1 if missing)
Substring(start, length)"hello".Substring(1, 3)"ell"
Replace(a, b)"a-b-c".Replace("-", "")"abc"
Split(sep)"a,b,c".Split(',')["a", "b", "c"]
string.Join(sep, items)string.Join("-", parts)"a-b-c"
string.IsNullOrWhiteSpace(s)string.IsNullOrWhiteSpace(" ")true

And for single characters, the char type has helpers: char.ToUpper(c), char.IsDigit(c), char.IsLetter(c).

To repeat a character, use new string('*', 5) → "*****".

Building strings

Concatenation with + works, but interpolation is clearer:

string first = "Ada", last = "Lovelace";
int born = 1815;
 
string a = "Name: " + first + " " + last + " (" + born + ")";
string b = $"Name: {first} {last} ({born})";      // same result, easier to read

Format specifiers

Inside { }, add a colon and a format:

double price = 1234.5;
Console.WriteLine($"{price:F2}");    // 1234.50   — 2 decimals
Console.WriteLine($"{price:N0}");    // 1,235     — thousands separator, no decimals
Console.WriteLine($"{0.256:P1}");    // 25.6 %    — percentage
Console.WriteLine($"{42,6}|");       //     42|   — right-aligned in 6 characters
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd}");

Special characters and multi-line text

string tab = "Name:\tAda";              // \t tab, \n new line, \" quote, \\ backslash
string path = @"C:\Users\Ada\file.txt"; // verbatim: backslashes are literal
 
string json = """
    {
      "name": "Ada",
      "born": 1815
    }
    """;                                 // raw string literal: no escaping at all

Comparing strings

== compares the text, which is what you want most of the time. For case-insensitive comparison:

bool same = string.Equals("Hello", "HELLO", StringComparison.OrdinalIgnoreCase);  // true

StringBuilder for building in loops

Because strings are immutable, += in a loop creates a new string every time. For many appends, use StringBuilder:

using System.Text;
 
var sb = new StringBuilder();
for (int i = 1; i <= 5; i++)
{
    sb.Append(i).Append(' ');
}
Console.WriteLine(sb.ToString());   // "1 2 3 4 5 "

Try it

Program.cs
Loading editor…

C# runtime not loaded

Key takeaways

  • Strings are immutable: methods return new strings — keep the result.
  • Index with s[0], s[^1], and ranges like s[1..4].
  • Prefer interpolation $"..." and use format specifiers like :F2 and :N0.
  • Use StringBuilder when building text piece by piece in a loop.

Exercise

Implement Initials ("ada", "lovelace" → "A.L."), FormatName which trims spaces and capitalizes only the first letter (" aDA " → "Ada"), and Mask which hides all but the last four characters of a card number ("1234567812345678" → "************5678").

Program.cs
Loading editor…

C# runtime not loaded

Hint 1

Get a character with an index: first[0]. char.ToUpper(c) uppercases a single character.

Hint 2

For FormatName: Trim() first, then combine char.ToUpper(t[0]) with t.Substring(1).ToLower().

Hint 3

new string('*', count) repeats a character. cardNumber.Substring(cardNumber.Length - 4) gives the last four.

Show solution
string Initials(string first, string last) =>
    $"{char.ToUpper(first[0])}.{char.ToUpper(last[0])}.";

string FormatName(string name)
{
    string trimmed = name.Trim();
    return char.ToUpper(trimmed[0]) + trimmed.Substring(1).ToLower();
}

string Mask(string cardNumber) =>
    new string('*', cardNumber.Length - 4) + cardNumber.Substring(cardNumber.Length - 4);

Console.WriteLine(Initials("ada", "lovelace"));
Console.WriteLine(FormatName("  aDA "));
Console.WriteLine(Mask("1234567812345678"));

Quiz

4 questions · 3 correct to pass
  1. 1.What does `"hello".ToUpper()` do to the original string?

  2. 2.What is `"C# rocks".Length`?

  3. 3.Which line prints a price as `$19.99`-style currency with two decimals?

  4. 4.When should you use StringBuilder?

To complete this lesson

  • ○ Solve the exercise
  • ○ Pass the quiz (3/4 correct)