15

I have a bunch of strings in my resource(.resx) file. I am trying to directly use them as part of switch statement (see the sample code below).

class Test
{
    static void main(string[] args)
    {
        string case = args[1];
        switch(case)
        {
            case StringResources.CFG_PARAM1: // Do Something1 
                break;
            case StringResources.CFG_PARAM2: // Do Something2
                break;
            case StringResources.CFG_PARAM3: // Do Something3
                break;              
            default:
                break;
        }
    }
}

I looked at some of the solutions, most of them seem to suggest that I need to declare them as const string which I personally dislike. I liked the top voted solution for this question: using collection of strings in a switch statement. But then I need to make sure that my enum and strings in resource file are tied together. I would like to know a neat way of doing that.

Edit: Also found this great answer while researching how to use Action:

Community
  • 1
  • 1
rkg
  • 5,559
  • 8
  • 37
  • 50

3 Answers3

29

You could use a Dictionary<string, Action>. You put an Action (a delegate to a method) for each string in the Dictionary and search it.

var actions = new Dictionary<string, Action> {
    { "String1", () => Method1() },
    { "String2", () => Method2() },
    { "String3", () => Method3() },
};

Action action;

if (actions.TryGetValue(myString, out action))
{
    action();
}
else
{
    // no action found
}

As a sidenote, if Method1 is already an Action or a void Method1() method (with no parameters and no return value), you could do

    { "String1", (Action)Method1 },
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • In general, this is a nicer construct than a switch statement, IMO. – SamStephens Feb 23 '11 at 21:18
  • @xanatos I understand this post is quite old, but wanted to know if this method of implementation is an example of a visitor pattern where the operation is defined by the action and the objects are defined as keys which in this case is a string? – Jaya Apr 23 '15 at 16:45
  • 1
    @JS_GodBlessAll I will say this example **isn't** a visitor patter, because in the visitor pattern, the object (the string in this case) must have an accept method that changes based on the object (the value of the string in this case), and a visitor that passes a reference to itself to the object. I'll say that this piece of code is more similar to http://stackoverflow.com/a/2604798/613130 the piece of code with *if (fruit is Orange)*, just with the various `Add` put inside a `Dictionary`. – xanatos Apr 23 '15 at 17:47
  • 1
    @JS_GodBlessAll The end result is similar to the Visitor pattern: the number of actions is expandable at runtime, so each object type could simply add itself to `actions`, but the way it is done is different (central dynamic dispatcher vs code inside objects to handle the visitor) – xanatos Apr 23 '15 at 17:48
  • @JS_GodBlessAll If you look http://en.wikipedia.org/wiki/Multiple_dispatch#C at the C example, the `collisionCases` is the `actions`, `collide(...)` is the example code I wrote – xanatos Apr 23 '15 at 17:51
  • @xanatos Thank you so much! Will keep reading to understand better. – Jaya Apr 23 '15 at 22:15
  • Could this be considered an example of the strategy pattern? – Chazt3n Jun 04 '15 at 19:08
  • This is nice and clean. Solved my problem. – Marlon Assef Feb 24 '21 at 00:24
9

You can't do that. The compiler must be able to evaluate the values, which means that they need to be literals or constants.

Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
0

I just came across this problem myself, and although this post is old, I thought I'd share my simple solution for other "Googlers"... I opted to change the switch...case to multiple if(...) elseif

class Test
{
    static void main(string[] args)
    {
        string case = args[1];
        if(case.Equals(StringResources.CFG_PARAM1))
        {
            // Do Something1
        }
        else if (case.Equals(StringResources.CFG_PARAM2))
        {
            // Do Something2
        }
        else if (case.Equals(StringResources.CFG_PARAM3))
        {
            // Do Something3
        }
        else
        {
            // Do something else
        }
    }
}

Definitely not as pretty as switch...case but has worked for me.

Dib
  • 2,001
  • 2
  • 29
  • 45