HomeSearch

C# String Switch Examples

Use a switch statement on a string for improved performance. String literal cases can be tested.
String switch. In the night sky a moth flutters its wings. It lands on a road sign. Imagine (just for a second) you are an entomologist. You are tracking moth populations.
Once data is collected, analysis begins. With a string switch statement in C# we can test strings (like names of moths or other flying insects). This even can impart a performance boost.
An example. A moth's name is just a string. We can use switch (on strings) to test whether a string is a moth name. Let's call our method that does this "IsMoth."

Tip: No fancy collections like a Dictionary or complex if-else chains are required here.

And: The C# compiler (our friend) will try to improve the switch's performance based on its internal heuristic (also known as magic).

IsMoth: Contains a switch case with 7 moth names in it. If any of those strings equal the parameter, it returns true. We have a moth name.

C# program that uses switch using System; class Program { static void Main() { Console.WriteLine(IsMoth("Ash Pug")); Console.WriteLine(IsMoth("Dot Net Perls")); } static bool IsMoth(string value) { switch (value) { case "Atlas Moth": case "Beet Armyworm": case "Indian Meal Moth": case "Ash Pug": case "Latticed Heath": case "Ribald Wave": case "The Streak": return true; default: return false; } } } Output True False
Internals. String switches are sometimes compiled into a custom Dictionary. Having 6 or more string cases and a default case resulted in the compiler generating a Dictionary.
Switch complexity 7 strings + default 6 strings + default 5 strings + default [and fewer] Compilation ldsfld class [mscorlib]System.Collections.Generic.Dictionary ldsfld class [mscorlib]System.Collections.Generic.Dictionary L_000b: call bool [mscorlib]System.String::op_Equality Output Compiler generated a Dictionary. Compiler generated a Dictionary. Compiler generated series if/conditionals.
ToLower. Switch cases must be constant. We cannot compare them case-insensitively without custom code. Here we normalize the string values with ToLower before entering the string switch.

Then: All the cases are lowercase. This results in a case-insensitive string switch.

Tip: The uppercase string "WHIPPET" was found to be a dog type. The value.ToLower() expression will match "whippet" in lowercase.

ToLower
C# program that uses switch, ToLower using System; class Program { static void Main() { Console.WriteLine(IsDogCaseInsensitive("WHIPPET")); Console.WriteLine(IsDogCaseInsensitive("sphynx")); } static bool IsDogCaseInsensitive(string value) { switch (value.ToLower()) { case "irish terrier": case "jagdterrier": case "keeshond": case "sulimov dog": case "whippet": case "eurasier": case "brittany": return true; default: return false; } } } Output True False
Null case. Most switch cases in C# a red on values (like 10 or 20) or string literals. But with the string switch we can match the null literal.

Note: In .NET Framework internals, null is like a 0 value, so it too is a constant—we call it the null literal constant.

C# program that uses null case in switch using System; class Program { static void Main() { foreach (string value in new string[] { null, "" }) { switch (value) { case null: // Can have a null case. Console.WriteLine("CASE NULL"); break; case "": // Empty string case also works. Console.WriteLine("CASE EMPTY"); break; } } } } Output CASE NULL CASE EMPTY
Abbreviations. A switch can handle abbreviations or synonyms. For example, in Excel spreadsheets, users will enter different column titles that mean the same thing.

So: We can use switches to tell the computer that "Height" is an abbreviation for "Ht."

Trim. We can use the Trim, TrimEnd, and TrimStart methods to try to normalize the input further. We can use TrimEnd to remove a period on the end of a string before using it in the switch.TrimTrimEnd, TrimStart
Benchmark. Here we see a benchmark of a switch expression versus an if/else chain expression. In the example, the compiler turns the string switch shown first into a Dictionary of strings.

Note: The benchmark compares this compiler optimization against the if-else chain that is used in the final method.

If
C# program that benchmarks string switch using System; using System.Diagnostics; class Program { const int _max = 100000000; static void Main() { string[] trees = new string[] { "Adler", "Persimmon", "???" }; int treeCount = 0; var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { foreach (string tree in trees) { if (IsTree(tree)) { treeCount++; } } } s1.Stop(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { foreach (string tree in trees) { if (IsTreeExpression(tree)) { treeCount++; } } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.Read(); } static bool IsTree(string value) { switch (value) { case "Alder": case "Elderberry": case "Chestnut": case "Guava": case "Willow": case "Elm": case "Persimmon": return true; default: return false; } } static bool IsTreeExpression(string value) { return (value == "Alder" || value == "Elderberry" || value == "Chestnut" || value == "Guava" || value == "Willow" || value == "Elm" || value == "Persimmon"); } } Output 32.94 ns switch (IsTree) 78.21 ns if (IsTreeExpression)
Result, above benchmark. In 2017, the switch version benchmarks faster. But here is an important point—in 2008 when I first tried this benchmark, the if-statement worked faster.

So: It may be useful to test the code on a system before you deploy it. Things might be wrong on the Internet.

Note: To achieve even better performance, you can try reordering the strings in an optimal way.

Tree: For complex situations where we have many strings and want to test them in a loop, consider a directed acyclic graph.

Tree
A review. A flying insect does not care about switch statements. But for data analysis of strings, we should care deeply about switch statements (and their syntax).
For performance, switches can be slower than if-statements. Often these small slowdowns do not matter. But when they do, an understanding of how switches work is important.Switch
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls