C# CharEnumerator Tips

Dot Net Perls
Char type

You want to test the CharEnumerator type in the .NET Framework and C# language. The CharEnumerator can be acquired through the GetEnumerator method on the string type; you can then use it to loop through the characters in a string. In this example, we demonstrate and also benchmark the CharEnumerator loops.

Example

To start, this program declares a string literal and then calls the GetEnumerator method on the string reference. We then use the while looping construct to repeatedly call the MoveNext method, which returns a bool. The Current property of the CharEnumerator returns the current character.

String Literal While Loop Examples
Program that uses CharEnumerator [C#]

using System;

class Program
{
    static void Main()
    {
	// Input string.
	string val = "dotnet";
	// Get enumerator.
	CharEnumerator e = val.GetEnumerator();
	// Use in loop.
	while (e.MoveNext())
	{
	    char c = e.Current;
	    Console.WriteLine(c);
	}
    }
}

Output

d
o
t
n
e
t

Performance

You should be aware of the other ways you can loop through strings, including the foreach and for loops. I wondered if the CharEnumerator version of the string loop had any advantage over these methods. This benchmark, then, tests a loop over a short four-character string using the CharEnumerator-style code, and the foreach-style code.

Loop Over String Chars
Program that benchmarks CharEnumerator [C#]

using System;
using System.Diagnostics;

class Program
{
    const int _max = 100000000;
    static void Main()
    {
	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    Method1("test");
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    Method2("test");
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }

    static int Method1(string val)
    {
	int res = 0;
	CharEnumerator c = val.GetEnumerator();
	while (c.MoveNext())
	{
	    res += (int)c.Current;
	}
	return res;
    }

    static int Method2(string val)
    {
	int res = 0;
	foreach (char c in val)
	{
	    res += (int)c;
	}
	return res;
    }
}

Results

33.33 ns
4.79 ns

Results. The results of the benchmark are that the CharEnumerator method of looping over all the characters in a string is much slower than the foreach method. There is a significant drawback to ever using the CharEnumerator in a loop on a string in the C# language.

Why?

Question and answer

Using the CharEnumerator directly in your code as shown in these examples is not appropriate. However, if you have code that requires a reference of type IEnumerator or IEnumerator<char>, you can use the CharEnumerator through those types because it implements those interfaces. This is not something that will occur in many programs.

Summary

.NET Framework information

The CharEnumerator type in the .NET Framework and C# language presents an implementation of an enumerator for the string type. To get a CharEnumerator, call GetEnumerator on a string instance. The performance of CharEnumerator is much worse than looping; for this reason, the CharEnumerator is only suitable for situations where an enumerator is absolutely required.

Char Type