Any reason for extending the c# switch statement?

Ever tried wanting to do more with the switch statement ? I personally like “switch” because it is such a nice way to avoid loads of nested if’s in your code, and to make the code smell good so that the code tells the story of what, not how.

But sometimes it just doesn’t cut it, like for instance when you want to test for intervals or parts of a string. Enter the ExtendedSwitch class, which works like this:

new ExtendedSwitch().
    Case(i > 0 && i <= 20, () => { Console.WriteLine("a");}).
    Case(i > 20 && i < 50, () => { Console.WriteLine("b"); }).
    Default(() => { Console.WriteLine("OOPS"); });

It is assumed by default that only one (the first) condition can be true.

Another usecase might be:

new ExtendedSwitch(ExtendedSwitch.Mode.MultiTrue).
    Case(s.StartsWith("A"), () => { Console.WriteLine("a"); }).
    Case(s.StartsWith("AB"), () => { Console.WriteLine("c"); }).
    Case(s.StartsWith("ABZ"), () => { Console.WriteLine("d"); }).
    Default(() => { Console.WriteLine("OOPS"); });

Note the Mode.MultiTrue which signifies that more than one delegate can be executed . The string “s” might contain “ABC” for example which would write out both “a” and “b”

So it looks like switch, but that is really more because of the formatting. Under the hood is simply a condition and a delegate. The Case() methods can be “piped” so to speak because on each call to the method it returns a reference to the object itself, while the object maintains state about whether a condition has been previously met. In this example lambdas are used, but it might as well have been delegate() { … } statements.

So here is the class for your enjoyment (or comment):

// Inspired by http://develocity.blogspot.com/2008/04/enhancing-c-switch-statement-with.html

/// <summary>
/// Class that chains together an extended switch/case concept, naking it possible to perform more wideranging tests
/// in the case function.
/// </summary>
public class ExtendedSwitch
{
    /// <summary>
    /// Set whether only the first true condition encountered will execute, or if every true condition executes.
    /// </summary>
    public enum Mode { SingleTrue, MultiTrue }

    // Secure that only one true (the first) is executed - functionally equvalent to "break"
    private bool m_break;
    private Mode m_switchmode;

    /// <summary>
    /// Default is Mode.SingleTrue
    /// </summary>
    public ExtendedSwitch()
    {
        m_break = false;
        m_switchmode = Mode.SingleTrue;
    }

    /// <summary>
    /// Set to one of the two Switch.Mode's
    /// </summary>
    /// <param name="switchmode"></param>
    public ExtendedSwitch(Mode switchmode)
    {
        m_break = false;
        m_switchmode = switchmode;
    }

    /// <summary>
    /// Case construct with a condition and a delegate.
    /// </summary>
    /// <param name="condition"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public ExtendedSwitch Case(bool condition, Action action)
    {
        if (m_break == true && m_switchmode == Mode.SingleTrue) return this;

        if (condition == true)
        {
            m_break = true;
            action();
        }
        return this;
    }

    /// <summary>
    /// Default if no conditions have been met - must be last in chain.
    /// </summary>
    /// <param name="action"></param>
    public void Default(Action action)
    {
        if (m_break == false)
            action();
    }
}
Advertisements
Posted in C#