c# – using collection of strings in a switch statement

c# – using collection of strings in a switch statement

Convert Commands into an enum:

enum Commands { ComandOne, CommandTwo, CommandThree, CommandFour }

Switch statement should look like:

static void Main(string[] args)
{
    Command = (Commands)Enum.Parse(typeof(Commands), args[0]);
    switch(Command)
    {
        case Commands.CommandOne: 
            //do something 
            break;
        case Commands.CommandTwo: 
            //do something else
            break;
        ...
        default:
            // default stuff
    }
}

And your last method should look like:

void DifferentMethod()
{
    foreach(var c in Enum.GetValues(typeof(Commands)))
    {
        string s = c.ToString(); 
        //do something funny
    }
}

An easy fix in your specific example:

switch(Array.IndexOf(Commands, Command))
{
    case 0: ...  
    case 1: ...

    default: //unknown command. Technically, this is case -1
} 

Other alternatives:

  1. Inline the strings.

    switch(Command)
    {
    case CommandOne: …
    case CommandTwo: …
    }

  2. Use an enumeration instead, as KirkWoll says. This is probably the cleanest solution.

  3. In more complex scenarios, using a lookup such as Dictionary<string, Action> or Dictionary<string, Func<Foo>> might provide better expressibility.

  4. If the cases are complex, you could create an ICommand interface. This will require mapping the command-string to the right concrete-implementation, for which you use simple constructs (switch / dictionaries) or fancy reflection (find ICommand implementations with that name, or with a certain attribute decoration).

c# – using collection of strings in a switch statement

Just yesterday i created a solution for it. In your case enums are better but here is my solution for general non-const switch-case situation.

usages:

    static string DigitToStr(int i)
    {
        return i
            .Case(1, one)
            .Case(2, two)
            .Case(3, three)
            .Case(4, four)
            .Case(5, five)
            .Case(6, six)
            .Case(7, seven)
            .Case(8, eight)
            .Case(9, nine)
            .Default();
    }

        int a = 1, b = 2, c = 3;
        int d = (4 * a * c - b * 2);
        string res = true
            .Case(d < 0, No roots)
            .Case(d == 0, One root)
            .Case(d > 0, Two roots)
            .Default(_ => { throw new Exception(Impossible!); });

        string res2 = d
            .Case(x => x < 0, No roots)
            .Case(x => x == 0, One root)
            .Case(x => x > 0, Two roots)
            .Default(_ => { throw new Exception(Impossible!); });

        string ranges = 11
            .Case(1, one)
            .Case(2, two)
            .Case(3, three)
            .Case(x => x >= 4 && x < 10, small)
            .Case(10, ten)
            .Default(big);

definition:

class Res<O, R>
{
    public O value;
    public bool succ;
    public R result;

    public Res()
    {

    }

    static public implicit operator R(Res<O, R> v)
    {
        if (!v.succ)
            throw new ArgumentException(No case condition is true and there is no default block);
        return v.result;
    }
}

static class Op
{
    static public Res<O, R> Case<O, V, R>(this Res<O, R> o, V v, R r)
    {
        if (!o.succ && Equals(o.value, v))
        {
            o.result = r;
            o.succ = true;
        }
        return o;
    }

    static public Res<O, R> Case<O, V, R>(this O o, V v, R r)
    {
        return new Res<O, R>()
        {
            value = o,
            result = r,
            succ = Equals(o, v),
        };
    }

    static public Res<O, R> Case<O, R>(this Res<O, R> o, Predicate<O> cond, R r)
    {
        if (!o.succ && cond(o.value))
        {
            o.result = r;
            o.succ = true;
        }
        return o;
    }

    static public Res<O, R> Case<O, R>(this O o, Predicate<O> cond, R r)
    {
        return new Res<O, R>()
        {
            value = o,
            result = r,
            succ = cond(o),
        };
    }

    private static bool Equals<O, V>(O o, V v)
    {
        return o == null ? v == null : o.Equals(v);
    }

    static public R Default<O, R>(this Res<O, R> o, R r)
    {
        return o.succ
            ? o.result
            : r;
    }

    static public R Default<O, R>(this Res<O, R> o, Func<O, R> def)
    {
        return o.succ ? o.result : def(o.value);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *