The instance method GetEnumerator() returns a CharEnumerator that walks through a string character by character. It powers foreach loops over strings and is useful when you need explicit control with MoveNext() and Current.
01
Instance Method
text.GetEnumerator()
02
CharEnumerator
Return type.
03
MoveNext()
Advance one char.
04
Current
Read char value.
05
foreach
Simpler alternative.
06
Forward Only
No going back.
Fundamentals
Definition and Usage
In C#, GetEnumerator() provides an enumerator for the characters in a string. Because string implements IEnumerable<char>, you can iterate characters with foreach—but calling GetEnumerator() directly shows how that works under the hood.
The returned CharEnumerator is a lightweight struct. Call MoveNext() to advance; when it returns true, read the character from Current. When it returns false, you have reached the end of the string.
💡
Beginner Tip
For everyday code, write foreach (char c in text) instead of manual MoveNext(). Learn GetEnumerator() to understand enumeration, interviews, and APIs that accept IEnumerator<char>.
Foundation
📝 Syntax
The public typed overload on System.String:
C#
public CharEnumerator GetEnumerator();
CharEnumerator members
MoveNext() — advances to the next character. Returns false at the end.
Current — the char at the current position (valid after MoveNext() returns true).
Reset() — returns to before the first character (rarely used).
Return Value
A CharEnumerator positioned before the first character. You must call MoveNext() before reading Current.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Manual enumeration
var e = text.GetEnumerator(); while (e.MoveNext()) { ... e.Current }
Simple foreach
foreach (char c in text) { ... }
Index-based loop
for (int i = 0; i < text.Length; i++) { text[i] }
Print each char
Console.Write(e.Current) inside while loop
Count characters
foreach or text.Length
GetEnumerator
text.GetEnumerator()
Explicit API
MoveNext
while (e.MoveNext())
Advance
Current
char c = e.Current
Read char
foreach
foreach (char c in text)
Preferred
Hands-On
Examples Gallery
Run with dotnet run. Each example shows how to iterate string characters—from manual CharEnumerator usage to foreach, counting, and index-based loops.
📚 Getting Started
Walk through characters with MoveNext() and Current.
Example 1 — Basic GetEnumerator() Usage
Obtain a CharEnumerator and print each character separated by spaces.
C#
using System;
class Program {
static void Main() {
string sampleString = "C# Enumerator";
CharEnumerator en = sampleString.GetEnumerator();
Console.Write("Characters: ");
while (en.MoveNext()) {
Console.Write(en.Current + " ");
}
}
}
📤 Output:
Characters: C # E n u m e r a t o r
How It Works
The enumerator starts before the first character. Each MoveNext() advances one position; Current then holds that character—including spaces. When the end is reached, MoveNext() returns false and the loop exits.
Example 2 — foreach Uses GetEnumerator() Internally
The same iteration with cleaner syntax—what most C# code uses daily.
C#
using System;
class Program {
static void Main() {
string text = "C#";
Console.Write("Via foreach: ");
foreach (char c in text) {
Console.Write(c + " ");
}
}
}
📤 Output:
Via foreach: C #
How It Works
The compiler translates foreach (char c in text) into calls to GetEnumerator(), MoveNext(), and Current. Prefer foreach unless you need manual enumerator control.
📈 Practical Patterns
Character counting, index access, and filtering.
Example 3 — Count Vowels with CharEnumerator
Process each character individually for custom validation logic.
C#
using System;
class Program {
static void Main() {
string word = "Enumerator";
int vowels = 0;
CharEnumerator en = word.GetEnumerator();
while (en.MoveNext()) {
char c = char.ToLower(en.Current);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
vowels++;
}
}
Console.WriteLine($"Vowels in '{word}': {vowels}");
}
}
📤 Output:
Vowels in 'Enumerator': 5
How It Works
Each character is inspected in order. This pattern suits custom checks—vowels, digits, symbols—without splitting the string into a new collection.
Example 4 — Index Loop When You Need Position
When you need the index as well as the character, a for loop is often clearer than CharEnumerator.
C#
using System;
class Program {
static void Main() {
string text = "ABC";
for (int i = 0; i < text.Length; i++) {
Console.WriteLine($"Index {i}: '{text[i]}'");
}
}
}
📤 Output:
Index 0: 'A'
Index 1: 'B'
Index 2: 'C'
How It Works
text[i] accesses the character at zero-based index i. Use this when position matters. CharEnumerator does not expose index directly—you would track it yourself.
Example 5 — Collect Digits with foreach
Build a new string from selected characters—a common filtering task.
C#
using System;
using System.Text;
class Program {
static void Main() {
string input = "Order #1042-A";
StringBuilder digits = new StringBuilder();
foreach (char c in input) {
if (char.IsDigit(c)) {
digits.Append(c);
}
}
Console.WriteLine($"Digits only: {digits}");
}
}
📤 Output:
Digits only: 1042
How It Works
foreach iterates every character; char.IsDigit filters numerals. The original string is unchanged—strings are immutable. Enumeration only reads characters.
Applications
🚀 Common Use Cases
Character-by-character validation — check each symbol in a password or identifier.
Custom parsing — walk input and build tokens without regex.
Learning IEnumerable — understand how foreach works on strings.
Legacy APIs — code that accepts or returns IEnumerator / CharEnumerator.
Streaming-style reads — forward-only processing of large strings one char at a time.
CharEnumerator is a struct—lightweight and stack-friendly.
Enumeration is forward-only; you cannot move backward.
Do not read Current before the first successful MoveNext().
foreach (char c in text) is the idiomatic alternative for most code.
Strings implement IEnumerable<char>, enabling LINQ like text.Count(c => ...).
Iteration does not modify the string—C# strings are immutable.
Performance
⚡ Optimization
GetEnumerator() and foreach over strings are efficient for typical lengths. For hot paths on large text, consider ReadOnlySpan<char> to avoid enumerator allocation patterns in some scenarios. For simple length checks, use text.Length instead of counting with an enumerator. Choose the style that balances readability and need.
Wrap Up
Conclusion
The C# GetEnumerator() method exposes character-by-character iteration through a CharEnumerator. It underpins foreach on strings and is valuable when you need explicit enumeration control or deeper understanding of IEnumerable<char>.
Practice the examples above, prefer foreach for daily code, then continue to GetHashCode() to learn how strings produce hash values.
Learn GetEnumerator to understand IEnumerable patterns
❌ Don’t
Assume you can rewind a CharEnumerator easily
Read Current before the first MoveNext()
Use manual enumeration when foreach is clearer
Modify characters during iteration expecting string to change
Count length by iterating when .Length exists
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about GetEnumerator()
Use these points whenever you iterate string characters in C#.
5
Core concepts
🔄01
CharEnumerator
Return type.
Basics
▶️02
MoveNext()
Advance one char.
Step
🔞03
Current
Read char value.
Access
📝04
foreach
Preferred syntax.
Daily use
🔒05
Immutable
Read-only walk.
Safety
❓ Frequently Asked Questions
GetEnumerator() returns a CharEnumerator that walks through each character in a string one at a time. Call it on a string: text.GetEnumerator(), then use MoveNext() and Current to read characters. It enables manual, forward-only iteration.
CharEnumerator en = text.GetEnumerator(); while (en.MoveNext()) { char c = en.Current; ... } The method takes no parameters and is an instance method on the string.
It returns CharEnumerator—a struct that implements IEnumerator<char>. Current holds the current char after a successful MoveNext(). MoveNext() returns false when there are no more characters.
Usually no. foreach (char c in text) is simpler and calls GetEnumerator() internally. Use the explicit CharEnumerator when you need manual control or are learning how enumeration works.
No. CharEnumerator is forward-only—you call MoveNext() repeatedly to advance. To revisit characters, get a new enumerator from the string or use a for loop with indices.
No. Strings are immutable. GetEnumerator() only reads characters. The original string stays unchanged while you iterate.
Did you know?
Since C# implements IEnumerable<char> on string, you can use LINQ directly: text.Count(char.IsUpper) or text.Where(c => char.IsDigit(c)). LINQ also uses enumeration internally—the same concept as GetEnumerator(), with a higher-level syntax.