Start learning free

LESSON 168 OF 347 · STRINGS

Introduction to Strings in C#: Characters, Indexing and Immutability

Reading Read the full explanation

Watch the lesson

Next lesson

C# · STRINGS

Intro To Strings in C#, explained

What a string is

A string is text: a sequence of characters kept in order. Names, messages, file paths and the input of many interview problems are all strings. In C# the type is string, which is a shorthand for the class System.String. The two names mean exactly the same thing.

A string is made of char values. A char holds one character and is written with single quotes, while a string is written with double quotes. These two lines look alike but have different types:

char letter = 'A';      // one character
string word = "A";      // a string that happens to contain one character

Mixing them up is a common beginner error: 'Hello' doesn't compile, because single quotes only hold a single character.

Creating strings

Put the text between double quotes. The empty string "" is valid and has no characters.

string greeting = "Hello";
string empty = "";
string quoted = "She said \"hi\"";
string path = @"C:\temp\file";

Inside a normal literal, a backslash starts an escape sequence: \" is a double quote, \\ is a backslash, \n is a new line and \t is a tab. A literal that starts with @ is a verbatim string, where backslashes are kept as they are. That is handy for paths.

Length and indexing

A string's size is its Length property. There are no parentheses after it, unlike a method call. Characters are numbered from 0, and square brackets read one of them:

string s = "Hello";
Console.WriteLine(s.Length);       // 5
Console.WriteLine(s[0]);           // H
Console.WriteLine(s[s.Length - 1]); // o

The valid indexes run from 0 to Length - 1. Reading s[5] here throws an IndexOutOfRangeException while the program runs. C# also lets you count from the end with ^, so s[^1] is the last character.

A for loop over the indexes visits every character, and so does foreach:

foreach (char ch in "Hi") {
    Console.Write(ch + "-");
}
// prints H-i-

Strings are immutable

Once a string exists, its characters can't be changed. This doesn't compile:

string myStr = "Bob";
myStr[0] = 'J';   // compile error: the indexer is read-only

Methods that look like they modify a string actually return a new one and leave the original alone:

string text = "hello";
text.ToUpper();                  // result is thrown away, text is still "hello"
text = text.ToUpper();           // now text is "HELLO"
Console.WriteLine(text.Replace('L', 'p')); // HEppO

Forgetting to assign the result back is a very common bug. To change characters one by one, copy them into a char[] with ToCharArray(), edit the array, and build a string back with new string(array). For many appends in a row, StringBuilder is the right tool, because it grows in place instead of copying the whole text each time.

Joining and comparing

The + operator joins strings, and string interpolation with $ puts values inside a literal:

string name = "Ann";
int age = 3;
Console.WriteLine("Hi " + name);          // Hi Ann
Console.WriteLine($"{name} is {age}");    // Ann is 3
Console.WriteLine(1 + 2 + "x" + 1 + 2);   // 3x12

The last line shows that + works left to right: 1 + 2 is still a number addition, and only after the first string appears does everything become text.

The == operator on two strings compares their contents, not their memory addresses, so it is the normal way to test equality:

string a = "He";
string b = new string(new[] { 'H', 'e' });
Console.WriteLine(a == b);   // True

The comparison is case-sensitive, so "abc" == "ABC" is false. For a case-insensitive check, use string.Equals(x, y, StringComparison.OrdinalIgnoreCase).

Empty and null

An empty string "" is a real string with Length 0. A string variable can also hold null, which means there is no string at all, and asking such a variable for its Length throws a NullReferenceException. string.IsNullOrEmpty(s) is true for both cases.

How this chapter uses strings

The lessons that follow treat a string as an indexed sequence of characters. You will read characters with s[i], loop over them, slice pieces with Substring, and build new strings. Knowing that strings are immutable explains the performance side of those lessons: building a result with repeated += copies the text every time, which costs O(n²) overall for a long string, while a StringBuilder or a char[] keeps it at O(n).

Key takeaways

  • string uses double quotes, char uses single quotes.
  • Length is a property, and indexes run from 0 to Length - 1.
  • Strings are immutable: methods return new strings, so assign the result back.
  • == compares the text of two strings.
  • Use ToCharArray() or StringBuilder when you need to change or build text efficiently.
Keep going with C#About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
Start learning free