BuildQuill
C# learning path
4 of 25
Lesson 4 of 25
Lesson 4Beginner16 min

C# Strings and Text

Build, inspect, compare, and normalize text while understanding why strings behave differently from mutable containers.

Before this lesson

  • Variables and types
  • Basic Console output

Create and combine strings with interpolation

Inspect and transform text without assuming mutation

Compare user-facing text deliberately

The short answer

A string represents a sequence of text characters. C# strings are immutable: operations such as Trim, Replace, and ToUpper return a new string rather than changing the existing value.

01

Text is data, not decoration

Names, addresses, search terms, log messages, and file contents all enter programs as text. A string stores an ordered sequence. Its Length reports how many UTF-16 code units it contains, and an index such as text[0] reads one char at a zero-based position. Index zero is the first position because it is an offset of zero from the start.

An empty string, "", is a real string containing no characters. It is different from a string containing one space, " ", and different again from null, which means no string value is present. That distinction becomes important when validating input.

C#
string code = "CSharp";

Console.WriteLine(code.Length);
Console.WriteLine(code[0]);
Console.WriteLine(code[code.Length - 1]);

Expected output

6
C
p
02

Combine values for people to read

Concatenation joins strings with +, but a long chain of text and variables becomes difficult to scan. Interpolation begins with $ and evaluates expressions inside braces. It keeps the sentence shape visible and supports numeric and date formats.

Escape sequences represent characters that would otherwise be hard to place in a quoted literal. \n starts a new line, \t inserts a tab, " represents a quote, and \ represents a backslash. Verbatim strings prefixed with @ treat backslashes literally, which is convenient for Windows paths and multi-line text, although embedded quotes are doubled.

C#
string customer = "Omar";
int orderNumber = 27;
decimal total = 31.5m;

Console.WriteLine($"Order #{orderNumber} for {customer}: {total:0.00}");

Expected output

Order #27 for Omar: 31.50
03

String methods return new strings

Strings are immutable. Once a particular string value exists, its characters do not change. A method such as Trim creates and returns another string. If you call rawName.Trim() without storing or using the result, rawName still includes its spaces.

Immutability makes strings safe to share, but repeatedly appending inside a large loop can create many temporary strings. StringBuilder is an alternative when constructing a large piece of text through many updates. For ordinary messages and a small number of joins, interpolation is clearer and fast enough.

NeedPreferReason
Readable message with valuesInterpolationKeeps the sentence visible
Two or three fixed piecesInterpolation or +Both remain clear
Many appends in a loopStringBuilderAvoids repeated intermediate strings
Join a collection with a separatorstring.JoinExpresses the intent directly
04

Comparison depends on the rule

The == operator compares string contents using an ordinal, case-sensitive comparison. That may be right for a code or exact identifier and wrong for a command typed by a person. A login name, file path, and human-language word can each require different comparison rules.

For simple command input, string.Equals(command, "quit", StringComparison.OrdinalIgnoreCase) makes the case rule explicit. Do not normalize culturally meaningful text with ToLower and assume every language behaves like English. Choose a StringComparison value that matches the domain.

C#
using System;

class Program
{
  static void Main()
  {
      string command = "QUIT";

      bool shouldStop = string.Equals(
          command,
          "quit",
          StringComparison.OrdinalIgnoreCase);

      Console.WriteLine(shouldStop);
  }
}

Expected output

True

Good habits

  • Trim input when surrounding whitespace is not meaningful.
  • Check length before reading an index supplied by a user or calculation.
  • Use string.IsNullOrWhiteSpace when blank input should count as missing.

Quick knowledge check

Answer before you reveal.

01After name.Trim(); runs by itself, has name changed?

No. Trim returns a new string. Assign the result or use it directly.

02Is the last character at text[text.Length]?

No. Indexes start at zero, so the last valid index is text.Length - 1.

Practice challenge

Now build it without copying.

Start with a product name containing extra outer spaces. Clean it, print its length, create a lowercase hyphenated slug, and print a one-line product summary.

You are done when

  • The original and cleaned strings are stored separately
  • The slug contains no spaces
  • The summary uses interpolation

Stretch: Compare two differently cased product codes using both == and OrdinalIgnoreCase, then explain the different results in output labels.

Open challenge in playground

Lesson checkpoint

One small step locks it in

Mark this lesson complete, then keep the momentum going.

Complete and continue

Clear up the details

Frequently asked questions

What is the difference between char and string?

char holds one UTF-16 code unit and uses single quotes. string holds a sequence and uses double quotes. Some visible Unicode symbols require more than one char.

Should I always call ToLower before comparing?

No. Use an explicit StringComparison when possible; it communicates the intended case and culture rules without creating another string.

When is StringBuilder worth using?

Use it when a program builds substantial text through many appends, especially in loops. It is unnecessary ceremony for a few values in one message.