views:

72

answers:

2

What is a good collection/container to use for basically storing the contents of a switch-statement with multiple fallthrough situations? I guess, a more accurate way is, what's a good C# solution for a "many-keys-one-value" lookup? I checked through the System.Collections namespace and its associated namespaces, but didn't find anything that particularly lended itself to many-keys-one-value.

Recently, I wrote myself a small console program to construct and validate the XML files I need for my web application, to avoid the errors that occur when manually writing it. But for the initial version, I hardcoded a number of elements which are slightly mutable - specifically a few dictionaries for validation and one large switch-statement that has a hefty set of fallthrough options. While this will work for quite a few months to come, it may be necessary to eventually update these hardcoded elements, which currently would require editing the source file. In the interest of avoiding this, I decided that I'd store the dictionary and switch-statement information in an XML file (which eventually evolved, in a horribly recursive trend, to writing a program to construct and validate those XML files for me). Now, in storing this in a file, when I retrieve the data I can't simply rebuild the switch statement like I can the dictionaries. So I simply need to simulate the effect of a switch statement, which basically means I need several "keys" to reference the same "value".


Example snippet from the switch statement. This method will convert special value inputs into a corresponding ID, mostly to save on human memory space trying to memorize the values. Basically as illustrated, I'd like a container to store the several keys that all output a single value.

    private static string DiscernRegistrationId(string str)
{
    string retVal = str;
    switch (str.ToLowerKey()) //shortcut extension for str.Replace(" ","").Replace(".","").ToLowerInvariant()
    {
        case "computerpackage":
        case "comppackage":
        case "cpackage":
        case "computerpkg":
        case "comppkg":
        case "cpkg":
            retVal = "0x0100C73692D109C741A1B8846141B47519C8";
            break;
        case "mobilepackage":
        case "mobpackage":
        case "mpackage":
        case "mobilepkg":
        case "mobpkg":
        case "mpkg":
            retVal = "0x010081F753F0A4A5412CB6A8E9F8CD193F58";
            break;
        //More cases follow
    }
    return retVal;
}
+3  A: 

I would use ordinary Dictionary<string, string> and point all of the fall-through cases to the same string object.

svick
According to http://dotnetperls.com/string-switch, the switch statement will be compiled into a Dictionary<string, string>.
Chris Shouts
@paper1337: That's not surprising, however, I suspect there are cases when it chooses not to use that strategy (maybe if the number case statements is small). But, yeah, that optimization has been around since v1.0 of the compiler.
Brian Gideon
A: 

I think your best option is to stick with one of the builtin IDictionary<> classes and just duplicate the values. I would actually recommend a SortedDictionary<> in this case since it stores items in order by the key. That would be useful if you needed to print out the keys in manner that gives the same visual appearance as the switch statement.

Storing the values multiple times should not be an issue for you since they are strings which are reference types. Sure, you will have duplicate references to the same string, but it is not like you are duplicating the entire string's contents or anything.

Another thing to point out is that I believe the compiler is actually converting that switch statement into hashtable behind the scenes. That means it is probably using the same strategy I just recommended. Disassemble it and take a look.

Brian Gideon
The order by which the items from `SortedDictionary<K, V>` are sorted may not be the same as of the `switch` statement, that would require ordering by value. But it would work on certain types of input (like the one in the question).
svick
@svick: Good point.
Brian Gideon
Let's add @svick just to blink both of your envelopes. Are you two basically saying that there is no many-keys-one-value solution in C#? If that's the case, I will settle for a dictionary. It's not that repeated storage is a concern... I was simply hoping that there was a many-keys-one-value solution out there.
ccomet
@ccomet: Unfortunately, yes.
Brian Gideon
Very well then. I'll upvote @svick for the help, and accept this for the extended detail. Thanks to both of you!
ccomet