String
switch
Often we need to make a decision in code based on a string
's value. We can test characters, or lengths, but sometimes we need to match entire strings.
With a switch
statement, the C# compiler implements hidden optimizations to speed up matching. This can help programs go faster.
Here we use switch
(on strings) to test whether a string
is a moth name. Let's call our method that does this "IsMoth."
Dictionary
or complex if-else
chains are required here.switch
's performance based on its internal heuristic.IsMoth()
method contains a switch
case with 2 moth names in it. If any of those strings equal the parameter, it returns true.using System; class Program { static void Main() { Console.WriteLine(IsMoth("Ash Pug")); Console.WriteLine(IsMoth("?")); } static bool IsMoth(string value) { switch (value) { case "Atlas Moth": case "Ash Pug": return true; default: return false; } } }True False
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
.
string
switch
.string
"BLUE" was found to be a color. The value.ToLower()
expression will match "blue" in lowercase.using System; class Program { static void Main() { Console.WriteLine(IsColorCaseInsensitive("BLUE")); Console.WriteLine(IsColorCaseInsensitive("red")); } static bool IsColorCaseInsensitive(string value) { switch (value.ToLower()) { case "blue": case "red": case "yellow": case "green": return true; default: return false; } } }True True
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.
null
is like a 0 value, so it too is a constant—we call it the null
literal constant.using System; 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; } }CASE NULL CASE EMPTY
A switch
can handle abbreviations or synonyms. For example, in Excel spreadsheets, users will enter different column titles that mean the same thing.
Trim
, TrimEnd
, and TrimStart
methods to try to normalize the input further.string
switch
, and also remove ending spaces. Further string
logic could be added.using System; class Program { static bool IsHeight(string value) { // Match the trimmed value and return a bool. switch (value.Trim()) { case "Ht.": case "Height": return true; } return false; } static void Main() { Console.WriteLine("HEIGHT: {0}", IsHeight("Height")); Console.WriteLine("HEIGHT: {0}", IsHeight("Ht. ")); Console.WriteLine("HEIGHT: {0}", IsHeight("Width")); } }HEIGHT: True HEIGHT: True HEIGHT: False
Here we test a string
switch
against an if-else
chain expression. The C# compiler turns the string
switch
into a Dictionary
of strings. Then, cases perform a Dictionary
lookup.
string
switch
to test the tree name strings. The switch
is run in a tight loop.if-else
statements.switch
was faster here.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(); // Version 1: use string switch. for (int i = 0; i < _max; i++) { foreach (string tree in trees) { if (IsTree(tree)) { treeCount++; } } } s1.Stop(); var s2 = Stopwatch.StartNew(); // Version 2: use expression. 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")); } 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"); } }20.14 ns switch (IsTree) 21.33 ns if (IsTreeExpression)
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.