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
stringuses double quotes,charuses single quotes.Lengthis a property, and indexes run from 0 toLength - 1.- Strings are immutable: methods return new strings, so assign the result back.
==compares the text of two strings.- Use
ToCharArray()orStringBuilderwhen you need to change or build text efficiently.