S1.0 What This Teaches
string type and its operations:- String immutability and how assignment works
- Common instance methods: searching, splitting, replacing, trimming
- Interpolation, verbatim strings, and raw string literals
- Comparing strings correctly with
StringComparison StringBuilderfor high-performance concatenation- Span-based zero-allocation string operations
S1.1 Strings are Immutable
string in C# is an alias for System.String. Strings
are immutable: every method that appears to modify a string actually returns a
new string object:
string s = "Hello";
string upper = s.ToUpper(); // new string "HELLO"
Console.WriteLine(s); // still "Hello"
Console.WriteLine(upper); // "HELLO"
// == compares content, not reference
string a = "hello";
string b = "hel" + "lo";
Console.WriteLine(a == b); // True
Console.WriteLine(ReferenceEquals(a, b)); // may be True due to interning
S1.2 Common String Methods
string text = " Hello, World! ";
Console.WriteLine(text.Trim()); // "Hello, World!"
Console.WriteLine(text.TrimStart()); // "Hello, World! "
Console.WriteLine(text.Length); // 18
string s = "Hello, World!";
Console.WriteLine(s.ToUpper()); // "HELLO, WORLD!"
Console.WriteLine(s.ToLower()); // "hello, world!"
Console.WriteLine(s.Contains("World")); // True
Console.WriteLine(s.StartsWith("Hello")); // True
Console.WriteLine(s.EndsWith("!")); // True
Console.WriteLine(s.IndexOf("World")); // 7
Console.WriteLine(s.Substring(7, 5)); // "World"
Console.WriteLine(s.Replace("World", "C#")); // "Hello, C#!"
string[] parts = s.Split(", "); // ["Hello", "World!"]
string joined = string.Join(" | ", parts); // "Hello | World!"
S1.3 Interpolation, Verbatim, and Raw String Literals
string name = "Alice";
int age = 30;
// Interpolated string
string msg = $"Name: {name}, Age: {age}";
// Format specifiers inside interpolation
double pi = Math.PI;
Console.WriteLine($"Pi = {pi:F4}"); // Pi = 3.1416
// Verbatim string - backslashes are literal
string path = @"C:\Users\Alice\Documents";
// Raw string literal (C# 11) - no escape sequences at all
string json = """
{
"name": "Alice",
"age": 30
}
""";
Console.WriteLine(json);
S1.4 String Comparison
StringComparison when the comparison must be
culture-aware or case-insensitive. The default == is
ordinal and case-sensitive:
string a = "Hello";
string b = "hello";
Console.WriteLine(a == b); // False (case-sensitive)
Console.WriteLine(string.Equals(a, b, StringComparison.OrdinalIgnoreCase)); // True
// Sort order comparison
int cmp = string.Compare("apple", "Banana", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(cmp); // negative - "apple" comes first
S1.5 StringBuilder
+ creates a new string
object each iteration. StringBuilder builds into a mutable
buffer and is O(n) instead of O(n²):
using System.Text;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++)
{
sb.Append($"item{i}");
if (i < 4) sb.Append(", ");
}
string result = sb.ToString();
Console.WriteLine(result); // item0, item1, item2, item3, item4
sb.Clear();
sb.AppendLine("line 1");
sb.AppendLine("line 2");
Console.Write(sb);
S1.6 Example - All Together
// Strings - word frequency counter using string operations.
using System.Text;
string text = "the quick brown fox jumps over the lazy dog the fox";
string[] words = text.Split(' ');
var freq = new Dictionary<string, int>();
foreach (string w in words)
freq[w] = freq.GetValueOrDefault(w, 0) + 1;
var sorted = freq.OrderByDescending(kv => kv.Value).Take(5);
var sb = new StringBuilder("Top words:\n");
foreach (var (word, count) in sorted)
sb.AppendLine($" {word,-10} {count}");
Console.Write(sb);
Top words:
the 3
fox 2
quick 1
brown 1
jumps 1
S1.7 Exercise
Exercise
- Write a method that takes a sentence and returns it in title case
(first letter of each word capitalized). Use
Split,string.Join, andchar.ToUpper. - Write a method that checks if a string is a palindrome ignoring spaces
and case. Use
Replace,ToLower, and array reversal. - Use
StringBuilderto generate a CSV string from a list of tuples(string Name, int Score).
S1.8 Common Mistakes
Using + in loops for concatenation
result += piece inside a loop creates a new string on each
iteration. For more than a few iterations, use StringBuilder
or string.Join.
Comparing with == without specifying culture
== is ordinal and case-sensitive. Use
string.Equals(a, b, StringComparison.OrdinalIgnoreCase)
when you need case-insensitive comparison, and avoid
ToLower() == which allocates.
Off-by-one in Substring
string s = "Hello";
Console.WriteLine(s.Substring(1, 3)); // "ell" - start=1, length=3
// s[1..4] with range syntax is often clearer: s[1..4] = "ell"
S1.9 Key Terms
| Term | Meaning |
|---|---|
| immutable | String content cannot change after creation; all methods return new strings |
| string interpolation | $"..." embeds expressions directly in a string literal |
| verbatim string | @"..." treats backslashes as literal characters |
| raw string literal | """...""" (C# 11) - no escape sequences; whitespace is literal |
| StringBuilder | Mutable buffer for building strings efficiently in loops |
| StringComparison | Enum controlling culture and case sensitivity in comparisons |
| Span<char> | Zero-allocation window into string memory for slicing |
| string interning | Runtime reuse of identical string literals from a pool |