C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
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.
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("The Dev Codes"));
}
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
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.
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.
ToLowerC# 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
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
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.
TrimTrimEnd, TrimStartHere: We handle abbreviations in a string switch, and also remove ending spaces. Further string logic could be added.
C# program that uses switch with abbreviations, Trim method
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"));
}
}
Output
HEIGHT: True
HEIGHT: True
HEIGHT: False
Version 1: We use the string switch to test the tree name strings. The switch is run in a tight loop.
Version 2: We use an expression, which is compiled into something like a series of if-else statements.
IfResult: The string switch statement is faster. If we cannot test for the most common string first, a string switch can improve performance.
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();
// 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"));
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)
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