10

In my code, I'd like to work with textual names of the items that are coded as one symbol in packets.

In a usual situation, 1012 would mean cat, dog, cat, frog to me, but there are many more pairs like this, so it's hard to remember all of them. Sometimes they need to be changed, so I thought I should use a Dictionary<string, int> for that purpose. But then…

switch (symbol)
{
    case "0": { /* ... */ }
    case "1": { /* ... */ }
    case "2": { /* ... */ }
    case "n": { /* ... */ }
}

…becomes…

switch (symbol)
{
    case kvpDic["cat"]: { /* ... */ }
    case kvpDic["dog"]: { /* ... */ }
    case kvpDic["frog"]: { /* ... */ }
    case kvpDic["something else"]: { /* ... */ }
}

and the studio says I need to use constants for my switch.

How do I make it work?

Upd: number of such animals and their value pairs are only known at runtime, so the code must not use constants (I guess).

user1306322
  • 8,561
  • 18
  • 61
  • 122
  • What are you doing in the switch blocks? Basically you *won't* be able to switch on non-constant values, so you'll need to think of *some* alternative. There are various options, but we'll need more information. – Jon Skeet May 11 '12 at 18:12
  • 3
    Have you thought of using an `enum` instead? Or do the values change at runtime? – Dan Puzey May 11 '12 at 18:13
  • I assign Texture2D to a new sprite and they are unique to each situation. – user1306322 May 11 '12 at 18:14
  • What are you doing inside the case blocks? – scottm May 11 '12 at 18:21
  • It sounds like that could be wrapped in a single method and what's returned from your dictionary could be passed in. Can you post an example? – scottm May 11 '12 at 18:23
  • @scottm it's pretty simple, but most cases are unique, as I said. A texture is assigned to an object, sometimes to multiple objects, they are then marked to be animated and some checks are made to prevent possible bugs. – user1306322 May 11 '12 at 18:33

3 Answers3

20

You could store a Func<T> or Action in the dictionary instead.

var dict = new Dictionary<int, Action>();
dict.Add(1, () => doCatThing()); 
dict.Add(0, () => doDogThing());
dict.Add(2, () => doFrogThing());

Then, use it like so:

var action = dict[1];
action();
Sascha
  • 10,231
  • 4
  • 41
  • 65
scottm
  • 27,829
  • 22
  • 107
  • 159
  • 2
    "Action Dictionary" just sounds cool. Sounds like something I'd hear in a kids cartoon. Don't fear the Action Dictionary is here! – Servy May 11 '12 at 18:19
  • @Servy: Sounds like something you'd use to scare the crap out of children ;) – Niklas B. May 11 '12 at 18:26
  • 1
    Awesome! Though it took me some time to understand how exactly it works and plug possible holes. – user1306322 May 11 '12 at 19:55
  • Don't you guys think it's a bit of a bad practice to use an "Action Dictionary"? Shouldn't you try to decouple the code more? – JonaFane Oct 22 '19 at 06:12
1

It's not a VS restriction, it's a language restriction. So you won't be able to do exactly what you want. One idea would be to use an enum. An enum can't use a char value for it's entries, look at Why we can't have "char" enum types for some info on that.

Community
  • 1
  • 1
Sascha
  • 10,231
  • 4
  • 41
  • 65
1

You want to use an enum, not a dictionary.

enum AnimalsEnum { Dog, Cat, Bird, Fish };


public whathuh(AnimalsEnum whichAnimal) {
 switch(whichAnimal) {
   case AnimalsEnum.Dog:
   case AnimalsEnum.Cat:
...
}

}
Heather
  • 2,602
  • 1
  • 24
  • 33