Switch statements are rubbish. Only work on strings and numbers. Require an exact match value.
Let’s abuse, oh, to pick a C# feature at random, collection initialisers, and use it to make them better!
string switchValue = "house";
switch (switchValue)
{
case "hello":
Console.WriteLine("Value was hello");
break;
// But how can we handle, say, all other strings that start with h?
default:
Console.WriteLine("No match - Fallthrough");
break;
}
// here’s one way:
new Switch<string>(switchValue)
{
{ "hello",
()=> { Console.WriteLine("Value was hello"); }
},
{ x => x.StartsWith("h"),
()=> { Console.WriteLine("value started with h, but wasn't hello"); }
},
{ // default
() => { Console.WriteLine("No match - Fallthrough"); }
}
};
// how about a case insensitive comparison? switch (switchValue.ToLower()) ?
// or...
new Switch<string>(switchValue, StringComparer.InvariantCultureIgnoreCase)
{
{ "HOUSE", ()=> { Console.WriteLine("Value was house"); } },
{ x => x.StartsWith("H", StringComparison.InvariantCultureIgnoreCase),
()=> { Console.WriteLine("value started with h, but wasn't house"); }
},
{ () => { Console.WriteLine("No match - Fallthrough"); } }
};
// what about an expression equivalent?
string val = new Switch<string, string>(switchValue)
{
{ "hello", ()=> "Value was hello" },
{ x => x.StartsWith("h"), ()=> "value started with h, but wasn't hello" },
{ () => "No match - Fallthrough" }
};
Console.WriteLine(val);
// what about things other than strings?
DateTime today = DateTime.Today;
// can't switch (today)... but we can Switch<DateTime> on it:
new Switch<DateTime>(today)
{
{ new DateTime(2009, 01, 01), () => { Console.WriteLine("Happy 2009!"); } },
{ day => day.Day == 1,
() => { Console.WriteLine("It's the first day of a new month"); }
},
{ () => { Console.WriteLine("Nothing happening today"); } }
};
I should point out that I do have an implementation of the Switch class used here (well, technically Switch classes, and a bonus point to anyone paying enough attention to spot the second one), and it works exactly as shown, but I've less of an urge to share the grubby details of the implementation than to show the twisted client code it enables.
Next time on Dangerous Ideas in C#, we'll see what havoc can be wrought with 'yield return' statements.